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 声明。不幸的是,命名空间很复杂,但在许多情况下是必不可少的。对它们有一个基本的了解。