Если вы хотите сопоставить все узлы, следующие за <A>
, но перед следующим <A>
, я думаю, вы можете использовать что-то вроде этого:
<xsl:template match="A">
<xsl:copy>
<!-- start of range -->
<xsl:variable name="start" select="count(preceding-sibling::*) + 1" />
<!-- end of range -->
<xsl:variable name="stop">
<xsl:choose>
<!-- either just before the next A node -->
<xsl:when test="following-sibling::A">
<xsl:value-of select="count(following-sibling::A[1]/preceding-sibling::*) + 1" />
</xsl:when>
<!-- or all the rest -->
<xsl:otherwise>
<xsl:value-of select="count(../*) + 1" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- this for debugging only -->
<xsl:attribute name="range">
<xsl:value-of select="concat($start + 1, '-', $stop - 1)" />
</xsl:attribute>
<!-- copy all nodes in the calculated range -->
<xsl:for-each select="../*[position() > $start and position() < $stop]">
<xsl:copy-of select="." />
</xsl:for-each>
</xsl:copy>
</xsl:template>
Для вашего ввода:
<root>
<A />
<ab />
<ac />
<A />
<ab />
<ac />
</root>
Я получаю (я оставил атрибут range, чтобы сделать вычисления видимыми):
<A range="2-3">
<ab />
<ac />
</A>
<A range="5-6">
<ab />
<ac />
</A>