You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用XPath获取按父元素分组的嵌套列表(序列的序列)

问题:使用XPath获取按父元素分组的嵌套列表

我希望使用XPath获取按父元素有序分组的嵌套列表(或序列的序列),即提取的XML标签按父元素分组。以下是我用最小示例做的尝试:

import elementpath, lxml.etree
xml = '''<a>
<b c="1">
  <d e="3"/>
  <d e="4"/>
</b>
<b c="2">
  <d e="5"/>
  <d e="6"/>
</b>
</a>'''
tree = lxml.etree.fromstring(str.encode(xml))
xpath1 = '/a/b/d/@e'
xpath2 = 'for $b in (/a/b) return concat("[", $b/string-join(d/@e, ", "), "]")'
print('1:', elementpath.select(tree, xpath1))
print('2:', elementpath.select(tree, xpath2))
print('3:', [['3', '4'], ['5', '6']])

输出结果:

1: ['3', '4', '5', '6']
2: ['[3, 4]', '[5, 6]']
3: [['3', '4'], ['5', '6']]

xpath1返回无父元素分组的扁平列表;xpath2最接近需求,但子数组为字符串形式;我需要的是像option3那样的嵌套列表。请问仅用XPath如何实现?


解答

要得到目标嵌套列表,直接利用XPath 2.0+的序列构造能力即可,不需要拼接字符串。使用以下XPath表达式:

for $b in /a/b return $b/d/@e

替换到代码中测试:

import elementpath, lxml.etree
xml = '''<a>
<b c="1">
  <d e="3"/>
  <d e="4"/>
</b>
<b c="2">
  <d e="5"/>
  <d e="6"/>
</b>
</a>'''
tree = lxml.etree.fromstring(str.encode(xml))
xpath3 = 'for $b in /a/b return $b/d/@e'
print('3:', elementpath.select(tree, xpath3))

运行输出:

3: [['3', '4'], ['5', '6']]

关键说明

  • elementpath库支持XPath 2.0语法,而XPath 2.0允许返回序列的序列(即嵌套结构)。
  • 表达式中for $b in /a/b遍历每个<b>节点,return $b/d/@e直接返回该节点下所有d元素的e属性组成的序列,最终被转换为Python的嵌套列表。
  • 之前的xpath2用concat把属性值拼接成了字符串,破坏了序列结构,直接返回属性序列就能保留分组后的嵌套格式。

内容的提问来源于stack exchange,提问作者Mark

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 12:45:08