ElementTree XPath - 根据属性选择元素

时间:2008-10-21 15:52:52

标签: python elementtree

我在ElementTree中使用属性XPath Selector时遇到问题,我应该可以根据Documentation

进行操作

以下是一些示例代码

XML

<root>
 <target name="1">
    <a></a>
    <b></b>
 </target>
 <target name="2">
    <a></a>
    <b></b>
 </target>
</root>

的Python

def parse(document):
    root = et.parse(document)
    for target in root.findall("//target[@name='a']"):
        print target._children

我收到以下例外情况:

expected path separator ([)

2 个答案:

答案 0 :(得分:34)

您尝试使用的语法是 ElementTree 1.3 中的新内容。

此类版本附带 Python 2.7 或更高版本。 如果你有Python 2.6或更低版本,你仍然有ElementTree 1.2.6或更少。

答案 1 :(得分:18)

此代码中存在几个问题。

  1. Python的buildin ElementTree(简称ET)没有真正的XPATH支持;仅限于有限的子集例如,它不支持 find-from-root 表达式,如//target

    注意:documentation 提到“ // ”,但仅限于儿童:所以表达为 .//target有效; //...不是!

    还有另一种实现:lxml更丰富。对于内置代码,使用文档的接缝。这与/工作不符。

  2. @name表示法选择xml- 属性; xml-tag中的key=value表达式。

    因此,名称值必须为1或2才能选择给定文档中的内容。或者,可以使用子元素 'a'target[a](无@)搜索目标。

  3. 对于给定的文档,使用内置的ElementTree(v1.3)解析为root,以下代码是正确且有效的:

    • root.findall(".//target")查找两个目标
    • root.findall(".//target/a")找到两个a-element
    • root.findall(".//target[a]")这会再次找到两个target-element,因为它们都有一个a-element
    • root.findall(".//target[@name='1']")仅查找第一个目标。请注意,需要大约1的引号;否则会引发一个SyntaxError
    • root.findall(".//target[a][@name='1']")也有效;找到目标
    • root.findall(".//target[@name='1']/a")只找到一个a元素; ...