XPath选择两个特定元素之间的所有元素

Mir*_*rko 30 xml xslt xpath

我有一个以下的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>
Run Code Online (Sandbox Code Playgroud)

我想在第一个divider元素之后选择所有p个节点,直到下一次出现divider元素.我试着跟随xpath:

//divider[1]/following-sibling::p[following::divider]
Run Code Online (Sandbox Code Playgroud)

但问题是它在最后一个divider元素之前选择所有p个元素.我不知道如何使用xpath 1来做到这一点.

Dan*_*ley 28

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

/*/p[count(preceding-sibling::divider)=1]
Run Code Online (Sandbox Code Playgroud)


Dim*_*hev 19

这是一个通用的XPath表达式:

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

如果您替换$k,1那么p选择所需的节点.

如果你$k用第二和第三之间的2所有p元素替换divider,......等

说明:

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

$ns1[count(.|$ns2) = count($ns2)]
Run Code Online (Sandbox Code Playgroud)

选择属于所有节点向节点集$ns1$ns2.

在这个具体案例中,我们$ns1用以下代替

/*/divider[$k]/following-sibling::p
Run Code Online (Sandbox Code Playgroud)

我们$ns2用以下代替:

/*/divider[$k+1]/preceding-sibling::p
Run Code Online (Sandbox Code Playgroud)


byt*_*ter 5

那么选择所有p只有一个元素dividerpreceding-sibling呢?

//doc/p[preceding-sibling::divider[1] and not (preceding-sibling::divider[2])]
Run Code Online (Sandbox Code Playgroud)


Mic*_*Kay 5

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

/doc/divider[2]/preceding-sibling::p[preceding-sibling::divider]
Run Code Online (Sandbox Code Playgroud)

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