Python XPath SyntaxError:无效谓词

时间:2015-11-20 15:52:37

标签: python xml xpath

我正在尝试解析像

这样的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出了什么问题?

跟进

谢谢你,你的解决方案有效。我有一个跟进。现在,我希望获得带有文本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)

但有更好的方法吗?

2 个答案:

答案 0 :(得分:10)

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)

答案 1 :(得分:1)

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

dependency