使用 xml.etree.ElementTree 获取子节点的所有实例

Posted

技术标签:

【中文标题】使用 xml.etree.ElementTree 获取子节点的所有实例【英文标题】:Getting all instances of child node using xml.etree.ElementTree 【发布时间】:2015-05-29 18:28:13 【问题描述】:

我有以下 XML 文件作为输入:

<Test>
  <callEvents>
    <moc>
      <causeForTermination>0</causeForTermination>
      <serviceCode>
        <teleServiceCode>11</teleServiceCode>
      </serviceCode>
      <dialledDigits>5555555</dialledDigits>
      <connectedNumber>77777</connectedNumber>
    </moc>

    <moc>
      <causeForTermination>0</causeForTermination>
      <serviceCode>
        <teleServiceCode>11</teleServiceCode>
      </serviceCode>
      <dialledDigits>2222222</dialledDigits>
    </moc>
  </callEvents>
  <callEventsCount>100</callEventsCount>
</Test> 

我想输出 dialledDigits 的所有值。但是,我的代码只显示 dialledDigits 的第一个实例。

dialledDigits  5555555

我想要的输出应该包含这两个实例。

dialledDigits  5555555
dialledDigits  2222222

这是我的代码

import xml.etree.ElementTree as ET
tree = ET.parse('as.xml')
root = tree.getroot()
callevent=root.find('callEvents')

Moc1=callevent.find('moc')

for node in Moc1.getiterator():
    if node.tag=='dialledDigits':
        print node.tag, node.attrib, node.text

【问题讨论】:

【参考方案1】:

您还可以编写 XPath 表达式。只需 2 行而不是 5 行和一个循环:

for node in tree.findall('.//callEvents/moc/dialledDigits'):
    print node.tag, node.attrib, node.text 

演示:

>>> import xml.etree.ElementTree as ET
>>> 
>>> 
>>> tree = ET.parse('as.xml')
>>> root = tree.getroot()
>>> 
>>> for node in tree.findall('.//callEvents/moc/dialledDigits'):
...     print node.tag, node.attrib, node.text
... 
dialledDigits  5555555
dialledDigits  2222222

【讨论】:

是的,xpath 可以工作,谢谢。 xpath 方法不适用于 ET。它存在于lxml。 +点赞 xpath 语法在 ET 中可用:这就是 alecxe 在findall 调用中使用的语法...... 我只涉足了一点,从未使用过root = tree.getroot()。它在您的代码中使用,但我不明白为什么?【参考方案2】:

使用findall:

moc1 = callevent.findall('moc')

for moc in moc1:
    for node in moc.getiterator():
        if node.tag=='dialledDigits':
            print node.tag, node.attrib, node.text

输出:

dialledDigits  5555555
dialledDigits  2222222

【讨论】:

但是如果没有明确的 if 检查,难道不应该有办法做到这一点,而是像“for node in moc.inter("dialledDigits")”?【参考方案3】:

find()会返回第一个标签对象,所以使用finadall()会返回所有标签对象`

>>> Moc1=callevent.find('moc')
>>> Moc1
<Element 'moc' at 0x869a2ac>
>>> Moc1=callevent.findall('moc')
>>> Moc1
[<Element 'moc' at 0x869a2ac>, <Element 'moc' at 0x869a4ec>]
>>> 

迭代它:

>>> Mocs=callevent.findall('moc')
>>> for moc in Mocs:
...     for node in moc.getiterator():
...         if node.tag=='dialledDigits':
...             print node.tag, node.attrib, node.text
... 
dialledDigits  5555555
dialledDigits  2222222

【讨论】:

以上是关于使用 xml.etree.ElementTree 获取子节点的所有实例的主要内容,如果未能解决你的问题,请参考以下文章

python解析xml文件之xml.etree.cElementTree和xml.etree.ElementTree区别

使用 xml.etree.ElementTree 获取子节点的所有实例

术业有专攻:xml.etree.ElementTree

如何使用 python xml.etree.ElementTree 解析 eBay API 响应?

python xml.etree.ElementTree 附加到子元素

[python 学习] 使用 xml.etree.ElementTree 模块处理 XML