Skip to main content
 首页 » 编程设计

python之lxml.objectify 和前导零

2025年04月02日28me-sa

当在控制台上打印 objectify 元素时,前导零丢失,但它保留在 .text 中:

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

据我所知,objectify 自动使 b 元素成为 IntElement 类实例。但是,即使我尝试使用 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) 

打印:

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

如何强制 objectify 将此 b 元素识别为字符串元素?

请您参考如下方法:

根据文档和观察到的行为,XSD Schema 似乎仅用于验证,但不参与确定属性数据类型的过程任何。

例如,当一个元素在 XSD 中声明为 integer 类型,但 XML 中实际元素的值为 x01 时,元素无效异常正确提出:

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'. 

尽管关于 how data types are matchedobjectify 文档提到了 XML Schema xsi:type(链接部分中的第 4 个),那里的示例代码表明它意味着 通过直接在中添加 xsi:type 属性实际的 XML 元素,而不是通过单独的 XSD 文件,例如:

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