Validating and filling default values in XML based on XSD in Python
Question: 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.

