46

我在使用 ElementTree 中的属性 XPath Selector 时遇到问题,根据文档我应该能够做到这一点

这是一些示例代码

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 ([)
4

2 回答 2

36

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

此类版本随Python 2.7或更高版本一起提供。如果你有 Python 2.6 或更低版本,你仍然有 ElementTree 1.2.6 或更低版本。

于 2008-10-21T16:16:06.230 回答
29

这段代码有几个问题。

  1. Python 的内置 ElementTree(简称 ET)没有真正的 XPATH 支持;只有一个有限的子集例如,它不支持从根中查找表达式,例如//target.

    注意:文档 中提到了“ // ”,但仅适用于孩子:所以表达式 as .//target是有效的;//...不是!

    还有一个替代实现:lxml,它更丰富。对于内置代码,使用文档是接缝。那不匹配/工作。

  2. @name符号选择xml-属性;xml 标记中的key=value表达式。

    因此,名称值必须为 1 或 2 才能在给定文档中选择某些内容。或者,可以搜索带有子元素 “a”的目标:(target[a]没有@)。

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

  • root.findall(".//target") 找到两个目标
  • root.findall(".//target/a") 找到两个a元素
  • root.findall(".//target[a]")这会再次找到两个目标元素,因为它们都有一个 a 元素
  • root.findall(".//target[@name='1']")只找到第一个目标。请注意需要 1 左右的引号;否则会引发 SyntaxError
  • root.findall(".//target[a][@name='1']")也有效;找到那个目标
  • root.findall(".//target[@name='1']/a")只找到一个 a 元素;...
于 2013-04-19T13:00:16.117 回答