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

时间:2010-05-12 09:55: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>

示例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>

4 个答案:

答案 0 :(得分:34)

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

<xsl:if test="not(following-sibling::Unit)">

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

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

实现方式

<xsl:apply-templates select="SomeExpression"/>

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

<xsl:if test="position() = last()">
. . . . 
</xsl:if>

检查当前节点是node-list选择的<xsl:apply-templates>中的最后一个节点,而不是当前节点是最后一个兄弟节点。这完全回答了原始问题。

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

<xsl:template match="Unit[last()]">
    . . . . 
</xsl:template>

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

答案 1 :(得分:8)

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

<xsl:if test="not(following-sibling::Unit)">

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

<xsl:if test="position() = last()">

答案 2 :(得分: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>

    <?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>

答案 3 :(得分:4)

您可以针对position()

测试last()
<xsl:template match="Unit[@DeviceType = 'Node']">
 <!-- Am I the last Unit in this section of xml? -->     
 <xsl:if test="position() = last()">
   <!-- Yes I am! -->
   Last Unit
 </xsl:if>

 <div class="unitchild">
  Node: #<xsl:value-of select="@id"/>
 </div>
</xsl:template>

请参阅xsl:if上的w3schools文章。