在 xslt/xpath 中跟随或结束?

Following-or-end in xslt/xpath?

XPath Axes 包含指令 following:: 以获取所有后续节点的集合。

例如以下文件:

<?xml version="1.0" encoding="UTF-8"?>
<foo>
    <a/>
    <b/> <!-- access 1 -->
    <a/>
    <ca/>
    <a/>
    <b/>
    <a/>
    <a/>
    <cb/>
    <b/> <!-- access 2 -->
</foo>

例如,可以使用 following::a/preceding::b[1] 访问给定 <ca>access 1。换句话说,一个人希望访问:

the "last" <b> before the next <a>.

如果当前节点是<cb>,那么这个技巧就不再有效了,因为没有following::a。是否有 following-or-end 指令(或类似的东西)在那种情况下 returns 最后一个标签(</foo>),这样 access 2可以从<cb/>?

获得

这样的 following-or-next 应该读作:

The next <a> or the end of the file in case this doesn't exist.

因此请求的行为是:

+--------------+-----------------+-----------------------------------------+
| context-node | required result | current result                          |
+--------------+-----------------+-----------------------------------------+
| <ca>         | access 1        | access 1                                |
| <cb>         | access 2        | none (since following::a doesn't exist) |
+--------------+-----------------+-----------------------------------------+

同样,preceding-or-start 应该有用。

您可以使用以下方法找到您需要的内容:

( following-sibling::a[1]/preceding-sibling::b[1] | ../b[last()] )[1]

联合 (|) 运算符的左手参数将 return 下一个 a 之前的最后一个 b(如果没有 [=13,则为空集) =]), 右手参数总是 return 上下文节点的 last b 兄弟节点(不管那个特定的 b有以下 a 个兄弟姐妹)。总体 (...)[1] 然后 select 以文档顺序中的第一个为准。

即使最后一个 b 在上下文节点之前,这仍然有效,例如给出

<?xml version="1.0" encoding="UTF-8"?>
<foo>
    <a/>
    <b/> <!-- access 1 -->
    <a/>
    <ca/>
    <a/>
    <b/>
    <a/>
    <a/>
    <cb/>
    <b/> <!-- access 2 -->
    <cc/>
</foo>

如果 cc 是上下文节点,这个表达式仍然会 return "access 2"。

One can for instance use following::a/preceding::b[1] to access access 1 given <ca>.

不,这可以 select 多个节点 - 它 selects any <b>any 之前 关注 <a>


the "last" <b> before the next <a>.

那将是(我假设你实际上是指 following-sibling):

following-sibling::a[1]/preceding-sibling::b[1]

例如

<foo>
    <a/>
    <b/>
    <a/>   <!-- 3. preceding-sibling::b[1] - selected node -->
    <ca/>  <!-- 1. context node -->
    <a/>   <!-- 2. following-sibling::a[1] -->
    <b/>   
    <a/>   
    <a/>
    <cb/>
    <b/>
</foo>

当上下文为 <cb> 时,这仍然 select 没有任何内容,因此我们更改表达式以适应。

(
    following-sibling::a[1]/preceding-sibling::b[1]
    |
    following-sibling::b[1]
)[1]

The next <a> or the end of the file in case this doesn't exist.

给定 测试输入

<foo>
    <a id="1"/>
    <b id="2" /> <!-- access 1 -->
    <a id="3"/>
    <ca/>
    <a id="4"/>
    <b id="5"/>
    <a id="6"/>
    <a id="7"/>
    <cb/>
    <b id="8"/> <!-- access 2 -->
</foo>

以下XPath 表达式:

(following::a[1] | following::*[last()])[1]
当从 ca 的上下文中计算时,

将 select <a id="4"/>,当从 cb 的上下文中计算时,<b id="8"/>

]

可能有更好的方法来解决这个抽象问题背后的真实问题。