【问题标题】:Python XPath SyntaxError: invalid predicatePython XPath SyntaxError:无效谓词
【发布时间】:2016-02-23 04:26:35
【问题描述】:

我正在尝试解析类似的 xml

<document>
    <pages>

    <page>   
       <paragraph>XBV</paragraph>

       <paragraph>GHF</paragraph>
    </page>

    <page>
       <paragraph>ash</paragraph>

       <paragraph>lplp</paragraph>
    </page>

    </pages>
</document>

这是我的代码

import xml.etree.ElementTree as ET

tree = ET.parse("../../xml/test.xml")

root = tree.getroot()

path="./pages/page/paragraph[text()='GHF']"

print root.findall(path)

但我得到一个错误

print root.findall(path)
  File "X:\Anaconda2\lib\xml\etree\ElementTree.py", line 390, in findall
    return ElementPath.findall(self, path, namespaces)
  File "X:\Anaconda2\lib\xml\etree\ElementPath.py", line 293, in findall
    return list(iterfind(elem, path, namespaces))
  File "X:\Anaconda2\lib\xml\etree\ElementPath.py", line 263, in iterfind
    selector.append(ops[token[0]](next, token))
  File "X:\Anaconda2\lib\xml\etree\ElementPath.py", line 224, in prepare_predicate
    raise SyntaxError("invalid predicate")
SyntaxError: invalid predicate

我的 xpath 出了什么问题?

跟进

感谢 falsetru,您的解决方案有效。我有一个跟进。现在,我想用文本GHF 获取段落之前的所有段落元素。所以在这种情况下,我只需要 XBV 元素。我想忽略ashlplp。我想这样做的一种方法是

result = []
for para in root.findall('./pages/page/'):
    t = para.text.encode("utf-8", "ignore")
    if t == "GHF":
       break
    else:
        result.append(para)

但是有没有更好的方法来做到这一点?

【问题讨论】:

    标签: python xml xpath


    【解决方案1】:

    ElementTree's XPath support is limited. 使用其他库,例如lxml:

    import lxml.etree
    root = lxml.etree.parse('test.xml')
    
    path="./pages/page/paragraph[text()='GHF']"
    print root.xpath(path)
    

    【讨论】:

    • 谢谢你!我也可以做类似 text.contains("something") 和 text.notContains("something") 的事情吗?
    • @AbtPst,您可以:path="./pages/page/paragraph[contains(text(),'something')]" / path="./pages/page/paragraph[not(contains(text(),'something'))]"
    • 不,你不能为find_all stackoverflow.com/questions/2637760/… 因为def prepare_predicate(next, token) 失败
    • 谢谢你!那行得通。它给了我我需要的所有元素。只是一个跟进。现在,如果我在看到“GHF”段落之前想要所有段落怎么办?一旦我看到带有文本“GHF”的段落,我想忽略它之后的所有其他内容。我可以这样做吗?
    • @AbtPst,请发布一个单独的问题,而不是更新当前问题。
    【解决方案2】:

    正如@falsetru 提到的,ElementTree 不支持text() 谓词,但它支持按文本匹配子元素,因此在此示例中,可以搜索具有paragraphpage带有特定文本,使用路径./pages/page[paragraph='GHF']。这里的问题是page 中有多个paragraph 标签,因此必须针对特定的paragraph 进行迭代。在我的情况下,我需要在 maven pom.xml 中找到 dependencyversion,并且只有一个 version 孩子,所以以下工作:

    In [1]: import xml.etree.ElementTree as ET
    
    In [2] ns = {"pom": "http://maven.apache.org/POM/4.0.0"}
    
    In [3] print ET.parse("pom.xml").findall(".//pom:dependencies/pom:dependency[pom:artifactId='some-artifact-with-hardcoded-version']/pom:version", ns)[0].text
    Out[1]: '1.2.3'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-26
      • 1970-01-01
      • 2013-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多