XPath查询包含指定ID或标题section的父component节点相关问题
问题原因分析
第一种写法报错原因
你写的.//*[title='Some s1 title']../../路径层级计算错误:
- 匹配逻辑:
*[title='Some s1 title']首先匹配到ID为S1的<section>节点(因为只有它有子节点<title>值匹配) - 第一个
../已经爬到了你需要的<component>节点(section的直接父节点) - 第二个
../继续爬到了<sB>节点,你最终返回的是sB节点下的所有子component,自然会返回S1、S2对应的两个component节点。
第二种写法报错原因
语法使用错误:.//*section[@ID='S1']/../里的*section是无效的节点名写法,*是匹配任意节点的通配符,不能直接拼接在节点名前面,这个错误导致表达式没有按你的预期匹配到<section ID='S1'>节点,自然无法爬到正确的父节点。
正确实现写法
两种需求都可以直接用条件筛选目标component,不需要反向爬父节点,逻辑更清晰:
- 按title文本匹配目标component
# 直接筛选包含符合条件title的component节点 res = tree.getroot().findall(".//component[section/title='Some s1 title']")
- 按section的ID属性匹配目标component
# 直接筛选包含符合ID的section的component节点 res = tree.getroot().findall(".//component[section/@ID='S1']")
如果一定要用反向爬父节点的写法,按sectionID查询的正确写法如下:
# 去掉错误的*通配符即可 res = tree.getroot().findall(".//section[@ID='S1']/..")
额外注意
xml.etree的XPath对文本匹配是严格全等的,如果你的节点文本包含前后空格(比如节点内容前后有缩进空格的情况),可以手动处理文本匹配,或者用lxml库替换标准库的xml.etree获取更完整的XPath功能支持。
内容的提问来源于stack exchange,提问作者gammapoint
相关产品推荐
相关产品推荐

