XPath:按特定顺序搜索多个节点

时间:2013-10-07 17:58:39

标签: xml xpath

我有一个包含“word”节点的“hello”节点的XML文件:

<doc>
    <hello>
        <word>Hello</word><word>World</word><word>!</word>
    </hello>
    <hello>
        <word>Hello</word><word>!</word><word>World</word>
    </hello>
    <hello>
        <word>Hello</word><word>World</word><word>!</word><word>blorf</word>
    </hello>
    <hello>
        <word>Hello</word><word>Wo</word><word>rld!</word>
    </hello>
</doc>

我想匹配第一个hello。第二个有错误的顺序,第三个有一个额外的单词。第四个有正确的文字,但分成不正确的单词。


此查询在XPath 1.0中有效,但非常冗长。有更简单的方法吗?

//hello[count(word) = 3 and word[1] = "Hello" and word[2] = "World" and word[3] = "!"]

这适用于XPath 2.0。有没有办法在XPath 1.0中做同等的事情?

//hello[deep-equal(data(subsequence(word,1)),('Hello','World','!'))]

3 个答案:

答案 0 :(得分:1)

您可以使用以下 XPATH 1.0

//hello[
  word[1][
    .='Hello' and following-sibling::word[1][
      .='World' and following-sibling::word[1][
        .='!' and count(following-sibling::word)=0
      ]
    ]
  ]
]

<强>输出

<hello>
    <word>Hello</word><word>World</word><word>!</word>
</hello>

答案 1 :(得分:1)

只需将整个Hello节点视为文本:

//hello[normalize-space(.) = "HelloWorld!"]

答案 2 :(得分:1)

如果您使用的是XPath 2.0,则可以使用string-join()添加分隔符来分隔单个单词。

//hello[string-join(word,'|')='Hello|World|!']

如果应该忽略空格,则可能需要使用normalize-space(word)

另一个XPath 2.0替代方法是使用deep-equal()来比较两个序列。这样会更安全,因为它不使用可能是文本值的一部分的分隔符。

//hello[deep-equal(data(subsequence(word,1)),('Hello','World','!'))]