tec*_*e11 2 python xml xpath python-3.x
我有一个像这样的 XML 文件:
$ cat sample.xml
<Requests>
<Request>
<ID>123</ID>
<Items>
<Item>a item</Item>
<Item>b item</Item>
<Item>c item</Item>
</Items>
</Request>
<Request>
<ID>456</ID>
<Items>
<Item>d item</Item>
<Item>e item</Item>
</Items>
</Request>
</Requests>
Run Code Online (Sandbox Code Playgroud)
Request我只是想提取对其孙元素具有一定价值的元素的 XML Item。这是代码:
bash-4.2$ cat xsearch.py
import sys
import xml.etree.ElementTree as ET
if __name__ == '__main__':
tree = ET.parse(sys.argv[1])
root = tree.getroot()
for request in root.findall(".//Item[.='c item']/../.."):
#for request in root.findall(".//Request[Items/Item = 'c item']"):
print(request)
Run Code Online (Sandbox Code Playgroud)
我收到“无效谓词”错误:
bash-4.2$ python3 xsearch.py sample.xml
Traceback (most recent call last):
File "/usr/lib64/python3.6/xml/etree/ElementPath.py", line 263, in iterfind
selector = _cache[cache_key]
KeyError: (".//Item[.='c item']/../..", None)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "xsearch.py", line 8, in <module>
for request in root.findall(".//Item[.='c item']/../.."):
File "/usr/lib64/python3.6/xml/etree/ElementPath.py", line 304, in findall
return list(iterfind(elem, path, namespaces))
File "/usr/lib64/python3.6/xml/etree/ElementPath.py", line 277, in iterfind
selector.append(ops[token[0]](next, token))
File "/usr/lib64/python3.6/xml/etree/ElementPath.py", line 233, in prepare_predicate
raise SyntaxError("invalid predicate")
SyntaxError: invalid predicate
Run Code Online (Sandbox Code Playgroud)
谁能指出我哪里错了?
一般来说,XPath无效谓词[错误意味着 XPath 的谓词之一(和之间的代码)在语法上有问题]。
具体就您的情况而言,存在两个问题:
这是因为谓词中SyntaxError("invalid predicate")有一个额外的内容:)
for request in root.findall(".//Item[.='c item')]/../.."):
^
Run Code Online (Sandbox Code Playgroud)
另请注意,您可以提升谓词以避免向下导航然后向上导航 ( ../..):
代替
.//Item[.='c item']/../..
Run Code Online (Sandbox Code Playgroud)
考虑
.//Request[Items/Item = 'c item']
Run Code Online (Sandbox Code Playgroud)
选择Request目标元素Item。
您正在使用的 XPath 库ElementTree 并不是 XPath 标准的完整实现。您可能会浪费大量时间来尝试确定 ElementTree 支持什么(".//Items[Item='c item']/.."恰好在这里工作)和不支持什么,但最好只使用更兼容的库,例如lxml。