XPath 语法错误:谓词无效

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)

谁能指出我哪里错了?

kjh*_*hes 6

一般来说,XPath无效谓词[错误意味着 XPath 的谓词之一(和之间的代码)在语法上有问题]

具体就您的情况而言,存在两个问题:

  1. 这是因为谓词中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

  2. 您正在使用的 XPath 库ElementTree 并不是 XPath 标准的完整实现。您可能会浪费大量时间来尝试确定 ElementTree 支持什么(".//Items[Item='c item']/.."恰好在这里工作)和不支持什么,但最好只使用更兼容的库,例如lxml