PoltoS PoltoS - 7 months ago 34
Python Question

Validating and filling default values in XML based on XSD in Python

How do I fill the default value in my XML during validation against XSD? If my attribute is not defined as

use="require"
and have
default="1"
, it could be possible to fill these default values from the XSD to the XML.

Example:
Original XML:

<a>
<b/>
<b c="2"/>
</a>


XSD scheme:

<xs:element name="a">
<xs:complexType>
<xs:sequence>
<xs:element name="b" maxOccurs="unbounded">
<xs:attribute name="c" default="1"/>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>


I want to validate the original XML using XSD and to fill all default values:

<a>
<b c="1"/>
<b c="2"/>
</a>


How do I get it in Python?
With validation there is no problem (e.g. XMLSchema). The problem are the default values.

Answer

To follow up on my comment, here's some code

from lxml import etree
from lxml.html import parse

schema_root = etree.XML('''\
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="a">
 <xs:complexType>
  <xs:sequence>
   <xs:element name="b" maxOccurs="unbounded">
    <xs:complexType>
     <xs:attribute name="c" default="1" type="xs:string"/>
    </xs:complexType>
   </xs:element>
  </xs:sequence>
 </xs:complexType>
</xs:element>
</xs:schema>''')

xmls = '''<a>
 <b/>
 <b c="2"/>
</a>'''

schema = etree.XMLSchema(schema_root)
parser = etree.XMLParser(schema = schema, attribute_defaults = True)

root = etree.fromstring(xmls, parser)
result = etree.tostring(root, pretty_print=True, method="xml")

print result

will give you

<a>
 <b c="1"/>
 <b c="2"/>
</a>

I've modified your XSD slightly, wrapped xs:attribute in xs:complexType and added schema namespace. To have your defaults filled in, you need to pass attribute_defaults=True to etree.XMLParser() and it should work.

Comments