按属性值选择元素的XPath

246

我有以下XML。

<?xml version="1.0" encoding="UTF-8"?>
<Employees>
    <Employee id="3">
        <age>40</age>
        <name>Tom</name>
        <gender>Male</gender>
        <role>Manager</role>
    </Employee>
    <Employee id="4">
        <age>25</age>
        <name>Meghna</name>
        <gender>Female</gender>
        <role>Manager</role>
    </Employee>
</Employees>

我希望选择id为"4"的Employee元素。

我正在使用下面的XPath表达式,但没有返回任何内容。

//Employee/[@id='4']/text()
我在http://chris.photobooks.com/xml/default.htm上检查了一下,它显示无效的xpath,不确定问题出在哪里。
3个回答

344
你需要在 [ 前删除 /。谓词(在 [..] 中的部分)不应该紧接着斜杠,而是直接跟在与它们相关联的节点选择器之后。
另外,为了选取 Employee 元素本身,你应该在末尾省略 /text()。否则,你只会选择 Employee 元素下面的空白文本值。
//Employee[@id = '4']

还有一件需要注意的事情://可能非常慢,因为它会在整个文档中查找匹配节点。如果你正在处理的文档结构将保持一致,最好使用更明确的路径,例如:

/Employees/Employee[@id = '4']

3
请注意,// 会选择和搜索文档中的 所有 节点,这可能会很慢。如果文档的结构已知,则应使用正确的路径,比如在 Gilles' 回答 中建议的那样。 - Jens
@Jens 是的,完全正确。我编辑了我的答案,加了一个附录。 - JLRishe

27
作为后续,您可以选择像这样“选择具有特定属性的所有节点”:
//*[@id='4']

12

试着做这个:

/Employees/Employee[@id=4]/*/text()

xmllint在查找ID之前是否会将整个XML文件加载到内存中?我有一个46 GB的XML文件,我正在其中查找ID。 - Hani Goc
5
46GB的XML文件-这就是问题所在。 - Gurwinder Singh
--stream:使用流接口处理非常大的文件。 - samwyse

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接