【问题标题】:Python xml parsing using lxml使用 lxml 解析 Python xml
【发布时间】:2018-01-20 13:27:28
【问题描述】:

我有如下的 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。请帮忙。

【问题讨论】:

标签: xml python-2.7 lxml


【解决方案1】:

快速回答是,您需要为您的.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 没有“字段”,只有元素、属性、cmets、处理指令、文本节点和 XML 声明。不幸的是,命名空间很复杂,但在许多情况下是必不可少的。对它们有一个基本的了解。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-22
    • 1970-01-01
    相关资源
    最近更新 更多