3

不必发布我的完整代码,因为我只有一个简短的问题。我在 XML Doc 中使用 XPath 搜索文本值。我有一个 XML Like

<key>Name</key>
<string>Dat Ass</string> 
<key>Artist</key>
<string>Earl Sweatshirt</string> 
<key>Album</key>
<string>Kitchen Cutlery</string> 
<key>Kind</key>
<string>MPEG-Audiodatei</string>

我有一个这样的表达式:

//string[preceding-sibling::key[text()[contains(., 'Name')]]]/text()

但这给了我所有以下字符串标签,我只想要第一个带有歌曲标题的标签。

迎接亚历克斯

4

2 回答 2

1

使用

(//string[preceding-sibling::key[1] = 'Name'])[1]/text()

或者,可以使用只进表达式:

(//key[. = 'Name'])[1]/following-sibling::string[1]/text()

请注意

这是一个常见的错误。任何类型的表达:

//someExpr[1]

不选择“从所有由//someExpr”选择的节点中的文档中的第一个节点。实际上它可以选择很多节点。

上面的表达式选择任何被选择的节点并且是//someExpr其父节点的第一个这样的子节点。

这就是为什么如果没有括号,这个问题的其他答案通常是不正确的。

于 2012-12-27T17:37:00.043 回答
0

您可以添加另一个谓词[1]来选择第一个匹配节点。嵌套谓词 usingtext()应该是不必要的:

//string[preceding-sibling::key[contains(., 'Name')]][1]/text()

选择此节点的另一种可能更有效的方法是

//key[contains(., 'Name')]/following-sibling::*[1][self::string]

这将选择想要的key节点之后的第一个节点(具有任何名称)并测试其名称是否为string.

于 2012-12-27T15:05:19.350 回答