为了账号安全,请及时绑定邮箱和手机立即绑定

在解析之前使用 lxml 注册命名空间

在解析之前使用 lxml 注册命名空间

大话西游666 2022-07-05 15:19:38
我正在使用 lxml 从具有名称空间的外部服务中解析 XML,但没有将它们注册到xmlns. 我正在尝试手动注册它register_namespace,但这似乎不起作用。from lxml import etreexml = """    <Foo xsi:type="xsd:string">bar</Foo>"""etree.register_namespace('xsi', 'http://www.w3.org/2001/XMLSchema-instance')el = etree.fromstring(xml) # lxml.etree.XMLSyntaxError: Namespace prefix xsi for type on Foo is not defined我错过了什么?奇怪的是,查看 lxml 源代码以尝试了解我可能做错了什么,似乎xsi命名空间应该已经作为默认命名空间之一存在。
查看完整描述

2 回答

?
PIPIONE

TA贡献1829条经验 获得超9个赞

当 XML 文档被解析然后再次保存时,lxml 不会更改任何前缀(并且register_namespace没有效果)。


如果您的 XML 文档未声明其命名空间前缀,则它不是命名空间格式良好的。在解析之前使用register_namespace无法解决此问题。


register_namespace定义序列化新创建的 XML 文档时要使用的前缀。


示例 1(不带register_namespace):

from lxml import etree


el = etree.Element('{http://example.com}Foo')

print(etree.tostring(el).decode())

输出:


<ns0:Foo xmlns:ns0="http://example.com"/>

示例 2(带register_namespace):

from lxml import etree


etree.register_namespace("abc", "http://example.com")


el = etree.Element('{http://example.com}Foo')

print(etree.tostring(el).decode())

输出:


<abc:Foo xmlns:abc="http://example.com"/>

示例 3(没有register_namespace,但具有与常规前缀关联的“知名”命名空间):

from lxml import etree


el = etree.Element('{http://www.w3.org/2001/XMLSchema-instance}Foo')

print(etree.tostring(el).decode())

输出:


<xsi:Foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>


查看完整回答
反对 回复 2022-07-05
?
慕无忌1623718

TA贡献1744条经验 获得超4个赞

使用自定义命名空间的命名空间格式良好的XML还必须包含命名空间声明本身。在第一个元素中添加一个xmlns就足够了:


from lxml import etree


xml = """

    <Foo xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:type='xsd:string'>bar</Foo>

"""

el = etree.fromstring(xml)    

print (el)

因此,从技术上讲,如果您的 XML 使用xsi但不包含命名空间声明,则它不是(命名空间)格式良好的 XML。


查看完整回答
反对 回复 2022-07-05
  • 2 回答
  • 0 关注
  • 248 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信