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

Python中XPath查找含指定文本的任意属性元素报错求助

问题描述

用户有如下XML文档:

<RootNode>
     <SubNode name="MainNode" SubNodeID="1">
       <SubSubNode SubSubID="10" SubSubName="Product Food">
         <Item subItemID="100" ItemName="Apple" OtherName="Gala"/>
         <Item subItemID="101" ItemName="Apple" OtherName="Aroma"/>
         <Item subItemID="102" ItemName="Pear" OtherName="Williams"/>
         <Item subItemID="103" ItemName="Pear" OtherName="Abate"/>
         <Item subItemID="104" ItemName="Cranberry" OtherName="Bilberry"/>
         <Item subItemID="105" ItemName="Cranberry" OtherName="Bluberries"/>
         <Item subItemID="106" ItemName="Strawberry" OtherName="Berry"/>
         <Item subItemID="107" ItemName="Peach" OtherName="Nectarina"/>
      </SubSubNode>
      <SubSubNode SubSubID="20" SubSubName="Product Beverage">
        <Item subItemID="108" ItemName="Cola" OtherName="Coca cola"/>
        <Item subItemID="109" ItemName="Cola" OtherName="Pepsi"/>
        <Item subItemID="110" ItemName="Orange Juice" OtherName="Fanta"/>
        <Item subItemID="111" ItemName="Soft drink" OtherName="Grape soda"/>
        <Item subItemID="112" ItemName="Soft drink" OtherName="Orange soda"/>
        <Item subItemID="113" ItemName="Soft drink" OtherName="Grape soda"/>
      </SubSubNode>
    </SubNode>
</RootNode>

使用Python标准库加载文档:

import xml.etree.ElementTree as ET

tree = ET.parse('Food.xml')
root = tree.getroot()

可以正常用XPath查找特定属性值的元素:

xPath = "SubNode/SubSubNode/Item[@OtherName='Gala']"
print(len(root.findall(xPath)))

但尝试用XPath查找任意属性包含指定文本的元素时,执行代码报错SyntaxError: invalid predicate,出错代码如下:

search_text = "berry"
xpath_expr = ".//*[@*[contains(., '{search_text}')]]"
解决办法

原因

Python标准库的xml.etree.ElementTree仅支持XPath 1.0的子集,不支持@*[contains(., 'xxx')]这种对任意属性使用contains()的语法,这是报错的核心原因。

方案1:使用lxml库(推荐)

lxml库支持完整的XPath 1.0语法,可以直接运行目标表达式。

操作步骤:

  1. 安装lxml:
pip install lxml
  1. 修改代码:
from lxml import etree

tree = etree.parse('Food.xml')
root = tree.getroot()

search_text = "berry"
# 用f-string格式化表达式,注意单引号的转义
xpath_expr = f".//*[@*[contains(., '{search_text}')]]"
matches = root.xpath(xpath_expr)

print(f"找到 {len(matches)} 个匹配元素")
for elem in matches:
    print(f"元素标签:{elem.tag},属性:{elem.attrib}")

方案2:不换库,手动遍历元素和属性

如果不想引入第三方库,可以遍历所有元素,逐个检查属性值是否包含目标文本:

import xml.etree.ElementTree as ET

tree = ET.parse('Food.xml')
root = tree.getroot()

search_text = "berry"
matches = []

# 遍历所有层级的元素
for elem in root.iter():
    # 检查当前元素的每个属性
    for attr_name, attr_value in elem.attrib.items():
        # 可根据需求决定是否忽略大小写
        if search_text.lower() in attr_value.lower():
            matches.append(elem)
            break  # 找到匹配属性后停止检查当前元素的其他属性

print(f"找到 {len(matches)} 个匹配元素")
for elem in matches:
    print(f"元素标签:{elem.tag},属性:{elem.attrib}")

说明:

  • 方案2的代码可实现和目标XPath完全相同的效果,还能灵活添加忽略大小写等自定义逻辑。
  • 如果需要严格匹配大小写,去掉代码中的.lower()即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 16:01:06