XSL - Как определить, является ли элемент последним в серии
У меня есть шаблон 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>
Ответы
Ответ 1
Если вы хотите проверить, является ли это последним элементом Unit на том же уровне (с одним и тем же родительским элементом), даже если есть произвольные теги до, после и между ними, это будет работать:
<xsl:if test="not(following-sibling::Unit)">
Однако, если вы применяете шаблоны для подмножества, последнее в документе может не быть в обрабатываемом наборе. Для этого вы можете проверить, есть ли position() = last()
<xsl:if test="position() = last()">
Ответ 2
Текущий выбранный ответ, как правило, неверен!
<xsl:if test="not(following-sibling::Unit)">
Это не будет работать с каким-либо XML-документом и любым <xsl:apply-templates>
Первоначальный вопрос касается последнего Unit
, а не последнего брата! Какой последний выбранный блок зависит только от выражения в атрибуте select <xsl:apply-templates>
, а не от физических свойств документа XML.
Способ сделать это:
<xsl:apply-templates select="SomeExpression"/>
, затем в шаблоне, который соответствует узлам, выбранным SomeExpression
:
<xsl:if test="position() = last()">
. . . .
</xsl:if>
Это проверяет, является ли текущий node последним в node-list
, выбранным <xsl:apply-templates>
, а не то, что текущий node является последним sibling. Это отвечает именно на первоначальный вопрос.
Если вопрос был оформлен по-другому, спрашивая, как узнать, является ли последний sibling Unit
текущим node, тогда лучшим решением было бы указать отдельный шаблон для этого последнего sibling node:
<xsl:template match="Unit[last()]">
. . . .
</xsl:template>
Обратите внимание на, что в этом случае нет необходимости писать какую-либо условную логику внутри шаблона, чтобы проверить, является ли текущий node "последним".
Ответ 3
Вы должны проверить позицию() = 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>
Ответ 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>
См. статью w3schools на xsl:if
.