I want to be able to “walk” a nested XSD using lxml from Python 3

只愿长相守 提交于 2019-12-13 06:47:59

问题


I know how to walk a basic XSD with lxml with Python 3

#!/usr/bin/python

#
# Go through an XSD, listing attributes and entities
#

import argparse
from lxml import etree

def do_element(elmnt):
     nam = elmnt.get('name')
     if len(elmnt) != 0:
        # Entity
        print("Entity: ", nam, " Type: ",elmnt.get('type','None'))
     else:
        # Attribute
        if nam != None:
             print("Attrib: ", nam, " Type: ",elmnt.get('type','None') )

def main():
    parser = argparse.ArgumentParser(prog='test')
    parser.add_argument('-d',action='store_true',help='debugging')

    parser.add_argument('infile')
    args = parser.parse_args()

    xsd_prs = etree.XMLParser(remove_blank_text=True)
    xsd_doc = etree.parse(args.infile, xsd_prs)
    xsd_doc.xinclude()

    walkall = xsd_doc.getiterator()
    for elmnt in walkall:
        do_element(elmnt)

if __name__ == "__main__":
    main()

which invokes do_element for every tag for the inputted XSD which in turn spits out some data about the attributes. The problem is that when I have an XSD with an import (in my current directory) so:

AAA.xsd:

<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema 
   elementFormDefault="qualified"
   targetNamespace="AAA"
   version="1"
   xmlns:xs="http://www.w3.org/2001/XMLSchema"
   xmlns:AAA="AAA"
   xmlns:BBB="BBB">
   <xs:import namespace="BBB" schemaLocation="BBB.xsd"/>
   <xs:element name="StringAttribute" type="xs:string">
   </xs:element>
   <xs:element name="ComplexEntity" type="BBB:ComplexEntityType">
   </xs:element>
</xs:schema>

and BBB.xsd:

<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema 
   elementFormDefault="qualified"
   targetNamespace="BBB"
   xmlns:BBB="BBB"
   xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <xs:complexType name="ComplexEntityType">
       <xs:sequence>
         <xs:element name="NestedString" type="xs:string">
         </xs:element>
      </xs:sequence>   
   </xs:complexType>
</xs:schema>

I would expect that by running with the file file: AAA.xsd, I could walk the definitions and into the namespace BBB. It doesn't happen. It gets to the element Item but will not decompose further in the ComplexType defined in BBB.xsd. I have tried reparsing xsd_doc as follows:

xsd_doc = etree.parse(args.infile)
xsd = etree.XMLSchema(xsd_doc)

and lxml blows up with:

lxml.etree.XMLSchemaParseError: Element '{http://www.w3.org/2001/XMLSchema}element', attribute 'type': References from this schema to components in the namespace 'subtypes' are not allowed, since not indicated by an import statement., line 35

The import is definitely there. Why doesn't it get followed?

来源:https://stackoverflow.com/questions/42395979/i-want-to-be-able-to-walk-a-nested-xsd-using-lxml-from-python-3

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!