Python ElementTree如何查找包含指定内容XML标签的元素?
如何用ElementTree查找包含特定子标签内容的元素
问题描述
尝试在Python的ElementTree中查找包含特定标签内容的元素,参考官方文档示例*[tag='text']编写代码,想要找到所有包含<note>NEW</note>的元素,但执行报错。
示例代码:
#!/usr/bin/env python import xml.etree.ElementTree as ET xml = """<?xml version="1.0"?> <entry> <foo>blah</foo> <foo>bblic</foo> <foo>fjdks<note>NEW</note></foo> <foo>fdfsd</foo> <foo>ljklj<note>NEW</note></foo> </entry> """ root = ET.fromstring(xml) print("Number of 'foo' elements: %d" % len(root.findall('.//foo'))) print("Number of new 'foo' elements: %d" % len(root.findall('.//[note="NEW"]')))
执行后触发报错:
$ python foo.py Number of 'foo' elements: 5 Traceback (most recent call last): File "/usr/lib/python3.10/xml/etree/ElementPath.py", line 370, in iterfind selector = _cache[cache_key] KeyError: ('.//[note="NEW"]',) During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/home/foo.py", line 17, in <module> print("Number of new 'foo' elements: %d" % len(root.findall('.//[note="NEW"]'))) File "/usr/lib/python3.10/xml/etree/ElementPath.py", line 411, in findall return list(iterfind(elem, path, namespaces)) File "/usr/lib/python3.10/xml/etree/ElementPath.py", line 384, in iterfind selector.append(ops[token[0]](next, token)) File "/usr/lib/python3.10/xml/etree/ElementPath.py", line 193, in prepare_descendant raise SyntaxError("invalid descendant") SyntaxError: invalid descendant
错误原因
使用的XPath路径.//[note="NEW"]存在语法错误:.//作为后代选择器,后面必须紧跟元素选择器(如具体标签名或通配符*),不能直接附加条件表达式,这就是触发SyntaxError: invalid descendant的核心原因。
正确实现方法
方法1:指定目标元素标签(推荐)
如果明确要查找的是<foo>元素,直接在XPath中指定标签名,再附加子元素匹配条件:
root.findall('.//foo[note="NEW"]')
方法2:匹配所有符合条件的元素
如果需要匹配任意包含<note>NEW</note>的元素,用通配符*代替具体标签名:
root.findall('.//*[note="NEW"]')
修改后的完整代码
#!/usr/bin/env python import xml.etree.ElementTree as ET xml = """<?xml version="1.0"?> <entry> <foo>blah</foo> <foo>bblic</foo> <foo>fjdks<note>NEW</note></foo> <foo>fdfsd</foo> <foo>ljklj<note>NEW</note></foo> </entry> """ root = ET.fromstring(xml) print("Number of 'foo' elements: %d" % len(root.findall('.//foo'))) # 使用正确的XPath路径 print("Number of new 'foo' elements: %d" % len(root.findall('.//foo[note="NEW"]')))
执行后会输出预期结果:
Number of 'foo' elements: 5 Number of new 'foo' elements: 2
内容的提问来源于stack exchange,提问作者user1235777
相关产品推荐
相关产品推荐

