Python,lxml – 获取兄弟标签(大)孩子的文本

我有一个XML解析,这对我来说真的很棘手.

<bundles>
  <bundle>
    <bitstreams>
      <bitstream>
        <id>1234</id>
      </bitstream>
    </bitstream>
    <name>FOO</name>
  </bundle>
  <bundle> ... </bundle>
</bundles>

我想迭代这个XML并找到比特流内的所有id值,其中name元素的值为’FOO’.我对任何未命名为“FOO”的捆绑包都不感兴趣,捆绑包中可能有任意数量的捆绑包和任意数量的比特流.

我一直在使用tree.findall(‘./ bundle / name’)来查找FOO包,但这只返回一个我无法单步执行id值的列表:

for node in tree.findall('./bundle/name'):
if node.text == 'FOO':
 id_values = tree.findall('./bundle/bitstreams/bitstream/id')
 for value in id_values:
     print value.text

这将打印出所有id值,而不是捆绑’FOO’的值.

如何遍历此树,找到名为FOO的包,获取此包节点并收集嵌套在其中的id值?这里的XPath参数不正确吗?

我在Python中工作,使用lxml绑定 – 但我认为任何XML解析器都没问题;这些不是大型的XML树.

解决方法:

您可以使用xpath来实现此目的.以下Python代码完美无缺:

import libxml2
data = """
<bundles>
  <bundle>
    <bitstreams>
      <bitstream>
        <id>1234</id>
      </bitstream>
    </bitstreams>
    <name>FOO</name>
  </bundle>
</bundles>
"""
doc = xmllib2.parseDoc(data)
for node in doc.xpathEval('/bundles/bundle/name[.="FOO"]/../bitstreams/bitstream/id'):
    print node

或使用lxml(数据与上例中的相同):

from lxml import etree

bundles = etree.fromstring(data)

for node in bundles.xpath('bundle/name[.="FOO"]/../bitstreams/bitstream/id'):
    print(node.text)

输出:

1234

如果<比特流>元素始终位于< name>之前在元素中,您还可以使用更高效的xpath表达式:

'bundle/name[.="FOO"]/preceding-sibling::bitstreams/bitstream/id'
上一篇:python – 使用lxml和xpath解析Html


下一篇:python网络爬虫学习及实践记录 | part03-数据解析【lxml和xpath的结合-实践部分】