3

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.

Linkid
  • 517
  • 5
  • 17
PoltoS
  • 1,232
  • 1
  • 12
  • 32
  • I have just asked a similar question to to see if this is supported in any validation library of any language http://stackoverflow.com/questions/4900867/is-there-a-xml-schema-validation-library-that-supports-the-default-attribute-valu – David W Feb 04 '11 at 17:21
  • I've not done this before, however, from [lxml documentation](http://lxml.de/validation.html#validation-at-parse-time) it looks like it will 'weave' the default values into the document. – jan zegan Nov 14 '11 at 22:20

1 Answers1

4

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.

jan zegan
  • 1,629
  • 1
  • 12
  • 18
  • And why do need to wrap xs:attribute in xs:complexType ? – PoltoS Nov 20 '11 at 23:38
  • May be you also know how to answer this question: http://stackoverflow.com/questions/4799838/is-it-possible-to-get-the-type-of-an-xml-node-as-it-was-defined-in-xsd – PoltoS Nov 21 '11 at 00:54