问题
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