XSLT - 选择另一个节点之后的节点

Sar*_*els 6 xml xslt select xquery

我正在尝试选择所有节点1)来自具有特定属性的节点并且2)自己具有特定属性.所以,如果我有以下XML:

<node id="1"><child attr="valueOfInterest"/></node>
<node id="2"><child attr="boringValue"/></node>
...
<node id="3"><child attr="valueOfInterest"/></node>
<node id="4"><child attr="boringValue"/></node>
<node id="5"><child attr="boringValue"/></node>
<node id="6"><child attr="boringValue"/></node>
...
Run Code Online (Sandbox Code Playgroud)

我的XSLT遍历每个node标记.在每一个node,我希望它选择所有以前node因为最近发生的小号node是有childattrvalueOfInterest.所以,如果我在节点#2,我想要一个空节点集.如果我在节点#6,我想选择节点#4和5.我目前有以下XSLT:

<xsl:variable name="prev_vals"
    select="preceding-sibling::node/child[@attr = $someValueICareAbout]/@attr"/>
Run Code Online (Sandbox Code Playgroud)

因此,此XSLT获取attr特定值的所有先前值.如何只得到这些前attr值是在node经过最近而来小号node,其child有一个特定的attr值(即,"valueOfInterest")?标签id上的属性node不保证会增加,因此我们无法与之进行比较.

编辑: 我认为这些可能有用:

<xsl:variable name="prev_children_of_interest"
    select="preceding-sibling::node/child[@attr != $someValueICareAbout]"/>
<xsl:variable name="mru_child_of_interest"
    select="$prev_children_of_interest[count($prev_children_of_interest)]"/>
Run Code Online (Sandbox Code Playgroud)

所以以前的所有child标签都有attr=valueOfInterest,然后是最近使用的(最接近当前节点)child标签,它具有我正在寻找的属性.从mru_child_of_interest我们可以找到最近使用的parent标记,但是我们如何查找该标记之后的节点?

Grz*_*ski 6

我不确定我是否正确理解你的问题,但这里有一些XSL 1.0(其他each-nodes属性仅供参考):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="nodes">
        <xsl:copy>
            <xsl:apply-templates select="node"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="node">
        <xsl:variable name="someValueICareAbout">valueOfInterest</xsl:variable>

        <xsl:variable name="recentParticularNode"
            select="preceding-sibling::node[child/@attr = $someValueICareAbout][1]"/>

        <xsl:variable name="recentParticularNodePosition"
            select="count($recentParticularNode/preceding-sibling::node) + 1"/>

        <xsl:variable name="currentPosition" select="position()"/>

        <xsl:if test="child/@attr != $someValueICareAbout">
            <each-nodes id="{@id}" cp="{$currentPosition}" 
                    rpnp="{$recentParticularNodePosition}">
                <xsl:copy-of
                    select="../node[position() &gt; $recentParticularNodePosition
                    and position() &lt; $currentPosition]"/>
            </each-nodes>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

输入XML:

<?xml version="1.0" encoding="UTF-8"?>
<nodes>
    <node id="1"><child attr="valueOfInterest"/></node>
    <node id="2"><child attr="boringValue2"/></node>
    <node id="3"><child attr="valueOfInterest"/></node>
    <node id="4"><child attr="boringValue4"/></node>
    <node id="5"><child attr="boringValue5"/></node>
    <node id="6"><child attr="boringValue6"/></node>
</nodes>
Run Code Online (Sandbox Code Playgroud)

结果XML:

<?xml version="1.0" encoding="UTF-8"?>
<nodes>
   <each-nodes id="2" cp="2" rpnp="1"/>
   <each-nodes id="4" cp="4" rpnp="3"/>
   <each-nodes id="5" cp="5" rpnp="3">
      <node id="4">
         <child attr="boringValue4"/>
      </node>
   </each-nodes>
   <each-nodes id="6" cp="6" rpnp="3">
      <node id="4">
         <child attr="boringValue4"/>
      </node>
      <node id="5">
         <child attr="boringValue5"/>
      </node>
   </each-nodes>
</nodes>
Run Code Online (Sandbox Code Playgroud)