【问题标题】:Using ElementTree to parse an XML string with a namespace使用 ElementTree 解析带有命名空间的 XML 字符串
【发布时间】:2011-12-14 20:28:54
【问题描述】:

我用谷歌搜索了我的裤子,但无济于事。我想做的很简单:我想使用 ElementTree 访问包含在字符串中的以下 XML 中的 UniqueID 值。

from xml.etree.ElementTree import fromstring

xml_string = """<ListObjectsResponse xmlns='http://www.example.com/dir/'>
        <Item>
                <UniqueID>abcdefghijklmnopqrstuvwxyz0123456789</UniqueID>
        </Item>
</ListObjectsResponse>"""

NS = "http://www.example.com/dir/"

tree = fromstring(xml_string)

我知道我应该使用fromstring 方法来解析XML 字符串,但我似乎无法确定如何访问UniqueID。对于命名空间,我不确定如何使用findfindallfindtext 方法。

非常感谢任何帮助。

【问题讨论】:

  • 你用谷歌搜索你的裤子了吗?搜索 "ElementTree find namespace" 发现这是第二次点击:"ElementTree: Working with Namespaces and Qualified Names"
  • 我读了整本书。恐怕仍然不太了解它以帮助解决我的困境。
  • @Raj 我也很少能完全理解 effobot 网站上的解释

标签: python xml elementtree


【解决方案1】:

以下内容应该可以帮助您:

>>> tree.findall('*/*')
[<Element '{http://www.example.com/dir/}UniqueID' at 0x10899e450>]

这列出了位于树根下两层的所有元素(在您的情况下为 UniqueID 元素)。或者,您可以使用tree.find() 在此级别仅找到 first 元素。然后就可以直接获取UniqueID元素的文本内容了:

>>> unique_id_elmt = tree.find('*/*')  # First (and only) element two levels below the root
>>> unique_id_elmt
<Element '{http://www.example.com/dir/}UniqueID' at 0x105ec9450>
>>> unique_id_elmt.text  # Text contained in UniqueID
'abcdefghijklmnopqrstuvwxyz0123456789'

或者,您可以通过指定其full path 来直接查找某些精确元素:

>>> tree.find('{{{0}}}Item/{{{0}}}UniqueID'.format(NS))  # Tags are prefixed with NS
<Element '{http://www.example.com/dir/}UniqueID' at 0x10899ead0>

正如 Tomalak 所指出的,Fredrik Lundh's site 可能包含有用的信息;您想检查如何处理 前缀:实际上可能有比在上述方法中显式指定 NS 路径更简单的方法来处理它们。

【讨论】:

  • 感谢您的示例。在这种情况下,我该如何打印实际的 UniqueID?
  • @Raj:我添加了显示如何获取 UniqueID 元素内容的代码。
【解决方案2】:

我知道我的回答会引起一些恐惧和反对作为报复,因为我使用模块 re 来分析 XML 字符串,但请注意:

  • 在大多数情况下,以下解决方案不会造成任何问题

  • 我希望投反对票的人能举例说明导致我的解决方案出现问题的案例

  • 我不解析字符串,使用“解析”一词的含义是“在分析树以查找要搜索的内容之前获取树”;我分析一下:我直接找到了文本中想要的部分

我并不假装必须始终在 re 的帮助下分析 XML 字符串。在大多数情况下,可能必须使用专用解析器解析 XML 字符串。我只是说,在这种简单的情况下,可以进行简单快速的分析,使用正则表达式工具更容易,顺便说一下,速度更快。

import re

xml_string = """<ListObjectsResponse xmlns='http://www.example.com/dir/'>
        <Item>
                <UniqueID>abcdefghijklmnopqrstuvwxyz0123456789</UniqueID>
        </Item>
</ListObjectsResponse>"""

print xml_string
print '\n=================================\n'

print re.search('<UniqueID>(.+?)</UniqueID>', xml_string, re.DOTALL).group(1)

结果

<ListObjectsResponse xmlns='http://www.example.com/dir/'>
        <Item>
                <UniqueID>abcdefghijklmnopqrstuvwxyz0123456789</UniqueID>
        </Item>
</ListObjectsResponse>

=================================

abcdefghijklmnopqrstuvwxyz0123456789

【讨论】:

  • +1:这种方法在某些情况下确实非常好。 is还有一个优点就是非常易读(搜索到的文字格式很明显)。
  • import reeeeeeeeee
猜你喜欢
  • 2012-09-27
  • 2015-03-06
  • 1970-01-01
  • 2014-09-24
  • 2013-01-28
相关资源
最近更新 更多