【问题标题】:lxml.objectify and leading zeroslxml.objectify 和前导零
【发布时间】:2016-06-27 21:05:45
【问题描述】:

在控制台打印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 元素识别为字符串元素?

【问题讨论】:

    标签: python xml xml-parsing lxml lxml.objectify


    【解决方案1】:

    根据文档和观察到的行为,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 matched 上的objectify 文档提到了XML Schema xsi:type(链接部分中的第4 个),但那里的示例代码表明它意味着通过添加@ 987654327@ 属性直接在实际的 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
    

    【讨论】:

    • 有趣的行为,很高兴看到它的解释!谢谢,很好的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多