Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

lxml.objectify and leading zeros

When the objectify element is printed on the console, the leading zero is lost, but it is preserved in the .text:

>>> from lxml import objectify
>>> 
>>> xml = "<a><b>01</b></a>"
>>> a = objectify.fromstring(xml)
>>> print(a.b)
1
>>> print(a.b.text)
01

From what I understand, objectify automatically makes the b element an IntElement class instance. But, it also does that even if I try to explicitly set the type with an XSD schema:

from io import StringIO
from lxml import etree, objectify

f = StringIO('''
   <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
     <xsd:element name="a" type="AType"/>
     <xsd:complexType name="AType">
       <xsd:sequence>
         <xsd:element name="b" type="xsd:string" />
       </xsd:sequence>
     </xsd:complexType>
   </xsd:schema>
 ''')
schema = etree.XMLSchema(file=f)
parser = objectify.makeparser(schema=schema)

xml = "<a><b>01</b></a>"
a = objectify.fromstring(xml, parser)
print(a.b)
print(type(a.b))
print(a.b.text)

Prints:

1
<class 'lxml.objectify.IntElement'>
01

How can I force objectify to recognize this b element as a string element?

like image 916
alecxe Avatar asked Jun 06 '26 16:06

alecxe


1 Answers

Based on the documentation and the behavior observed, it seems that XSD Schema is only used for validation, but isn't involved in the process of determining property data type whatsoever.

For example, when an element is declared to be of type integer in the XSD, but then the actual element in the XML has value of x01, element invalid exception is correctly raised :

f = StringIO(u'''
   <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
     <xsd:element name="a" type="AType"/>
     <xsd:complexType name="AType">
       <xsd:sequence>
         <xsd:element name="b" type="xsd:integer" />
       </xsd:sequence>
     </xsd:complexType>
   </xsd:schema>
 ''')
schema = etree.XMLSchema(file=f)
parser = objectify.makeparser(schema=schema)

xml = '''<a><b>x01</b></a>'''
a = objectify.fromstring(xml, parser)
# the following exception raised:
# lxml.etree.XMLSyntaxError: Element 'b': 'x01' is not a valid value of....
# ...the atomic type 'xs:integer'.

Despite objectify documentation on how data types are matched mentioned about XML Schema xsi:type (no. 4 in the linked section), the example code there suggests that it means by adding xsi:type attribute directly in the actual XML element, not via a separate XSD file, for example :

xml = '''
<a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <b xsi:type="string">01</b>
</a>
'''
a = objectify.fromstring(xml)

print(a.b)  # 01
print(type(a.b)) # <type 'lxml.objectify.StringElement'>
print(a.b.text) # 01
like image 192
har07 Avatar answered Jun 09 '26 05:06

har07



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!