【问题标题】:XPath: Search for several nodes in specific orderXPath:按特定顺序搜索多个节点
【发布时间】:2013-10-07 17:58:38
【问题描述】:

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

<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','!'))]

【问题讨论】:

    标签: xml xpath


    【解决方案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','!'))]
    

    【讨论】:

    • 您的第一个建议并不完全比 BeniBela 的好,但第二个正是我想要的。有没有办法在 xpath 1.0 中模拟它?
    • @bukzor - 据我所知,没有办法在 1.0 中模拟这一点。
    【解决方案2】:

    只需将整个 Hello-node 视为文本:

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

    【讨论】:

    • 贝尼贝拉:谢谢!您的方法适用于上面介绍的简单情况,但放弃了所有结构概念。我添加了您的查询匹配但不应该匹配的第四个案例。
    【解决方案3】:

    你可以使用下面的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>
    

    【讨论】:

    • 谢谢。您有不需要为每个孩子编制索引的解决方案吗?包含的短语可能是可变长度的。
    • @bukzor 我没听懂你...可能你正在使用 XPATH2.0..我只使用 1.0 版本..但是你说的垃圾是什么意思?
    • @bukzor 你只想要world 旁边是hello ..对吗?
    猜你喜欢
    • 1970-01-01
    • 2013-07-19
    • 1970-01-01
    • 2015-06-16
    • 2023-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多