【问题标题】:XPath select all elements between two specific elementsXPath 选择两个特定元素之间的所有元素
【发布时间】:2012-06-07 06:01:33
【问题描述】:

我有以下 xml:

<doc>
    <divider />
    <p>text</p>
    <p>text</p>
    <p>text</p>
    <p>text</p>
    <p>text</p>
    <divider />
    <p>text</p>
    <p>text</p>
    <divider />
    <p>text</p>
    <divider />
</doc>

我想选择第一个分隔元素之后的所有 p 节点,直到下一次出现分隔元素。我尝试使用以下 xpath:

//divider[1]/following-sibling::p[following::divider]

但问题是它选择最后一个分隔元素之前的所有 p 元素。我不确定如何使用 xpath 1。

【问题讨论】:

    标签: xml xslt xpath


    【解决方案1】:

    选择所有具有 一个 元素 dividerpreceding-siblingp 怎么样?

    //doc/p[preceding-sibling::divider[1] and not (preceding-sibling::divider[2])]
    

    【讨论】:

      【解决方案2】:

      与 bytebuster 相同的概念,但 xpath 不同:

      /*/p[count(preceding-sibling::divider)=1]
      

      【讨论】:

      • 好主意! count 更惯用,因为 1 只使用一次。
      【解决方案3】:

      这是一个通用的 XPath 表达式

      /*/divider[$k]
          /following-sibling::p
             [count(.|/*/divider[$k+1]/preceding-sibling::p)
             =
              count(/*/divider[$k+1]/preceding-sibling::p)
             ]
      

      如果您将$k 替换为1,则恰好选择了所需的p 节点。

      如果您将$k 替换为2,则第二个和第三个divider 之间的所有p 元素,...,等等。

      解释

      这是 Kayessian XPath 1.0 公式的简单应用,用于节点集交集:

      $ns1[count(.|$ns2) = count($ns2)]
      

      选择所有都属于节点集$ns1$ns2的节点。

      在这种特定情况下,我们将$ns1 替换为:

      /*/divider[$k]/following-sibling::p
      

      我们将$ns2 替换为:

      /*/divider[$k+1]/preceding-sibling::p
      

      【讨论】:

        【解决方案4】:

        我认为有一个更简单且可能更快的解决方案:您希望第二个分隔符的所有前面的兄弟姐妹至少有一个前面的兄弟分隔符:

        /doc/divider[2]/preceding-sibling::p[preceding-sibling::divider]
        

        当然,如果你想找到第二个和第三个分隔符之间的 paras,它会变得有点复杂:那么你需要更像 Daniel Haley 的解决方案。

        【讨论】:

        • 允许开始和结束分隔符标签变化,例如,可以在H1 和第一个TABLE 之间选择项目。简单灵活。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-23
        • 1970-01-01
        • 2022-01-03
        • 1970-01-01
        • 2014-12-04
        • 1970-01-01
        相关资源
        最近更新 更多