Python xml 使用 lxml 解析
Python xml parsing using lxml
我有如下 xml 个文件。
<sbe:messageSchema xmlns:sbe="http://www.fixprotocol.org/ns/simple/1.0"
description="something"
byteOrder="littleEndian">
<sbe:message name="DummyMsg" id="99" description="Placeholder message. Uses otherwise unused enums and composites so sbe compiles them.">
<field name="msgType" id="1" type="MsgType" />
<field name="minimumSbeSchemaVersion" id="2" type="MinimumSbeSchemaVersion"/>
</sbe:message>
</sbe:messageSchema>
xml 文件有多个 sbe:messageSchema 条记录。
尝试使用 lxml.etree
。如果我这样做 for child in root
,那么我会得到描述、字节顺序等,但不会 sbe:messageSchema。
另外,如果我尝试 root.iterfind('./sbe:message')
然后我会收到类似 sbe not found.
的错误
我想要sbe:messageSchema and its fields
。请帮忙。
快速回答是您需要为您的 .iterfind()
调用提供命名空间映射作为可选的第二个参数。名称空间映射只是一个字典,其中键是名称空间前缀,值是名称空间 URL.
大概你做了这样的事情:
doc = etree.parse(open('messages.xml'))
root = doc.getroot()
for child in root.iterfind('./sbe:message'):
print child
因为命名空间前缀是任意的并且可以随时重新映射到不同的 URL,所以您需要明确地告诉 lxml 前缀 sbe
与哪个命名空间 URL 相关联。如果您想在根元素中查看命名空间声明,请执行以下操作:
root.nsmap
你会看到这个:
{'sbe': 'http://www.fixprotocol.org/ns/simple/1.0'}
因此,简单地重用根元素中的命名空间声明:
doc = etree.parse(open('messages.xml'))
root = doc.getroot()
for child in root.iterfind('./sbe:message', root.nsmap):
print child
对于示例 XML 数据,您将打印一个 sbe:message
元素。
<Element {http://www.fixprotocol.org/ns/simple/1.0}message at 0x7f8175b92ef0>
我也感觉到一些关于基本 XML 概念的混淆。确保您了解格式良好的基本约束,以及元素属性与其子元素之间的区别。 XML 没有 'fields',只有元素、属性、注释、处理指令、文本节点和 XML 声明。不幸的是,命名空间很复杂,但在许多情况下是必不可少的。对它们有一个基本的了解。
我有如下 xml 个文件。
<sbe:messageSchema xmlns:sbe="http://www.fixprotocol.org/ns/simple/1.0"
description="something"
byteOrder="littleEndian">
<sbe:message name="DummyMsg" id="99" description="Placeholder message. Uses otherwise unused enums and composites so sbe compiles them.">
<field name="msgType" id="1" type="MsgType" />
<field name="minimumSbeSchemaVersion" id="2" type="MinimumSbeSchemaVersion"/>
</sbe:message>
</sbe:messageSchema>
xml 文件有多个 sbe:messageSchema 条记录。
尝试使用 lxml.etree
。如果我这样做 for child in root
,那么我会得到描述、字节顺序等,但不会 sbe:messageSchema。
另外,如果我尝试 root.iterfind('./sbe:message')
然后我会收到类似 sbe not found.
我想要sbe:messageSchema and its fields
。请帮忙。
快速回答是您需要为您的 .iterfind()
调用提供命名空间映射作为可选的第二个参数。名称空间映射只是一个字典,其中键是名称空间前缀,值是名称空间 URL.
大概你做了这样的事情:
doc = etree.parse(open('messages.xml'))
root = doc.getroot()
for child in root.iterfind('./sbe:message'):
print child
因为命名空间前缀是任意的并且可以随时重新映射到不同的 URL,所以您需要明确地告诉 lxml 前缀 sbe
与哪个命名空间 URL 相关联。如果您想在根元素中查看命名空间声明,请执行以下操作:
root.nsmap
你会看到这个:
{'sbe': 'http://www.fixprotocol.org/ns/simple/1.0'}
因此,简单地重用根元素中的命名空间声明:
doc = etree.parse(open('messages.xml'))
root = doc.getroot()
for child in root.iterfind('./sbe:message', root.nsmap):
print child
对于示例 XML 数据,您将打印一个 sbe:message
元素。
<Element {http://www.fixprotocol.org/ns/simple/1.0}message at 0x7f8175b92ef0>
我也感觉到一些关于基本 XML 概念的混淆。确保您了解格式良好的基本约束,以及元素属性与其子元素之间的区别。 XML 没有 'fields',只有元素、属性、注释、处理指令、文本节点和 XML 声明。不幸的是,命名空间很复杂,但在许多情况下是必不可少的。对它们有一个基本的了解。