XSL - 如何判断元素是否是序列中的最后一个

Chr*_*ris 11 xml xslt

我有一个选择执行的XSL模板(如下).我想做的是能够判断我是否是最后一个Unit匹配的.

  <xsl:template match="Unit[@DeviceType = 'Node']">
    <!-- Am I the last Unit in this section of xml? -->
    <div class="unitchild">
      Node: #<xsl:value-of select="@id"/>
    </div>
  </xsl:template>
Run Code Online (Sandbox Code Playgroud)

示例XML

<Unit DeviceType="QueueMonitor" Master="1" Status="alive" id="7">
    <arbitarytags />
    <Unit DeviceType="Node" Master="0" Status="alive" id="8"/>
    <Unit DeviceType="Node" Master="0" Status="alive" id="88"/>
</Unit>
Run Code Online (Sandbox Code Playgroud)

Dim*_*hev 35

当前选择的答案通常是不正确的!

<xsl:if test="not(following-sibling::Unit)">
Run Code Online (Sandbox Code Playgroud)

这不适用于任何XML文档和任何 <xsl:apply-templates>

最初的问题是关于最后一个Unit匹配,而不是最后一个兄弟!哪个匹配的最后一个单元仅取决于select属性中的表达式<xsl:apply-templates>,而不取决于XML文档的物理属性.

做到这一点的方法:

<xsl:apply-templates select="SomeExpression"/>
Run Code Online (Sandbox Code Playgroud)

然后在匹配选择的节点的模板中SomeExpression:

<xsl:if test="position() = last()">
. . . . 
</xsl:if>
Run Code Online (Sandbox Code Playgroud)

这将检查当前节点是否是node-list所选<xsl:apply-templates>节点中的最后一个节点,而不是当前节点是最后一个节点.这恰好回答了原始问题.

如果问题以不同的方式构建,询问如何识别最后一个兄弟Unit是否是当前节点,那么最好的解决方案是为最后一个兄弟节点指定一个单独的模板:

<xsl:template match="Unit[last()]">
    . . . . 
</xsl:template>
Run Code Online (Sandbox Code Playgroud)

请注意,在这种情况下,不需要在模板中编写任何条件逻辑来测试当前节点是否为"最后一个".


Mad*_*sen 8

如果你想测试它是否是同一级别的最后一个Unit元素(具有相同的父元素),即使之前,之后和之间存在任意标记,那么这将起作用:

<xsl:if test="not(following-sibling::Unit)">
Run Code Online (Sandbox Code Playgroud)

但是,如果要为子集应用模板,则文档中的最后一个可能不在正在处理的集合中.为此,你可以测试是否position() = last()

<xsl:if test="position() = last()">
Run Code Online (Sandbox Code Playgroud)


sha*_*unc 6

你应该测试position()= last(),但你应该在谓词中测试它,而不是在模板的主体中测试它:

<?xml version="1.0" encoding="utf-8"?>

<data>
    <item group="B">AAA</item>
    <item>BBB</item>
    <item group="B">CCC</item>
    <item>DDD</item>
    <item group="B">EEE</item>
    <item>FFF</item>
</data>
Run Code Online (Sandbox Code Playgroud)
    <?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:template match="data">
    <xsl:apply-templates select="item[@group]"/>
</xsl:template>

<xsl:template match="item">
    ITEM
    <xsl:if test="position() = last()">
    LAST IN CONTEXT
    </xsl:if>
</xsl:template>

<xsl:template match="item[position() = last()]">
    LAST ITEM
</xsl:template>
Run Code Online (Sandbox Code Playgroud)