【问题标题】:Finding an xml node by its name rather than by its index通过名称而不是索引查找 xml 节点
【发布时间】:2014-12-18 19:24:38
【问题描述】:

如何通过名称找到 xml 节点并在标签之间获取其值?

我是这样做的:

from xml.dom import minidom
dom = minidom.parseString(ET.tostring(ET.fromstring(some_xml), "utf-8"))
self.a1 = dom.childNodes[0].childNodes[4].childNodes[0].nodeValue
self.a2 = dom.childNodes[0].childNodes[5].childNodes[0].nodeValue

我想使用标签的名称而不是使用它在数组childNodes 中的索引来做到这一点。怎么样?

更新

<ReconnectResponse xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://ccc.aaa.bbb/api/v1"> 
  <ErrorMessage /> 
  <ErrorCode>0</ErrorCode> 
  <ServerTime>aaa</ServerTime> 
  <OAuthToken>bbb</OAuthToken> 
  <OAuthTokenSecret>ccc</OAuthTokenSecret> 
</ReconnectResponse>

和代码:

dom.getElementsByTagName("ServerTime") # => []

更新2

dom.toxml()
u'<?xml version="1.0" ?><ns0:ReconnectResponse xmlns:ns0="http://ccc.aaa.bbb/api/v1">\n  <ns0:ErrorMessage/>\n  <ns0:ErrorCode>0</ns0:ErrorCode>\n  <ns0:ServerTime>aaa</ns0:ServerTime>\n  <ns0:OAuthToken>bbb</ns0:OAuthToken>\n  <ns0:OAuthTokenSecret>ccc</ns0:OAuthTokenSecret>\n</ns0:ReconnectResponse>'

但我如何获得价值?我试过这个:

dom.getElementsByTagName("ns0:OAuthToken")
[<DOM Element: ns0:OAuthToken at 0x10635a878>]
(Pdb) dom.getElementsByTagName("ns0:OAuthToken")[0]
<DOM Element: ns0:OAuthToken at 0x10635a878>
(Pdb) dom.getElementsByTagName("ns0:OAuthToken")[0].nodeValue
(Pdb) dom.getElementsByTagName("ns0:OAuthToken")[0].toxml()
u'<ns0:OAuthToken>aaaaaa</ns0:OAuthToken>'

【问题讨论】:

  • 通常 xpath 是非常标准的方法。你明确想要minidom 吗?或者你可以使用lxml吗?
  • 看起来你正在使用 elementtree -- 你不能只是root.find(tagname)吗?
  • @stanleyxu2005, minidom。

标签: python xml dom minidom


【解决方案1】:

你需要使用getElementsByTagNameNS,因为你没有一个名为ServerTime的标签,你有一个名为{http://ccc.aaa.bbb/api/v1}ServerTime的标签(其中{http://ccc.aaa.bbb/api/v1}表示默认命名空间。)

getElementsByTagNameNS("http://ccc.aaa.bbb/api/v1", "ServerTime")

由于文档元素的 last 属性,此命名空间隐式添加到 XML 正文中的每个标记:

<ReconnectResponse ... xmlns="http://ccc.aaa.bbb/api/v1">

【讨论】:

  • 我可以确认它在没有命名空间的情况下也可以工作。
  • 这可能取决于您的 Python/lxml/ET/minidom 版本,因为没有命名空间对我来说它不起作用。如果不使用dom.getElementsByTagNameNS(),我会得到一个空列表,就像 OP 一样。以this eval.in 为例。
  • 感谢您的回复。很高兴知道。
【解决方案2】:

通常使用lxml 和 xpath 是 Python 中的常用方法。

由于您想显式使用minidom,您可以使用以下方法获取特定标签的所有HTML元素。

matches = dom.getElementsByTagName("foo")
for e in matches:
    print(e.firstChild.nodeValue)

【讨论】:

  • 实际上,dom.getElementsByTagName("my_tag") 出于某种原因总是返回 []。
  • @AlexanderSupertramp 最好将您的 xml 内容粘贴到您的问题中。
  • @AlexanderSupertramp 我可以得到 'aaa' 的结果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-07
  • 2018-09-22
相关资源
最近更新 更多