Это работает, но не так, как вы думаете ....
В вашем первом шаблоне у вас есть это xsl:apply-templates
<xsl:apply-templates select="group[position()=2]/Function" />
Но у вас нет подходящего шаблонаFunction
, и поэтому встроенный шаблон правил XSLT запускает, что это ...
<xsl:template match="*|/">
<xsl:apply-templates/>
</xsl:template>
Это выберет элементы Group
, для которых снова естьнет шаблона.Теперь, когда он делает <xsl:apply-templates/>
, он выберет все дочерние узлы, включая пустые текстовые узлы, используемые для отступа в XML.
Проблема в том, что когда вы тестируете position() = last()
, вы тестируете положениеэлемент в наборе всех выбранных дочерних узлов, который включает в себя текстовые узлы.После последнего id
есть пустой текстовый узел, поэтому id
может быть последним id
элементом, но это не последний дочерний узел.
Одно из решений - сообщить XSLT обрезатьпустые текстовые узлы, так что id
становится последним дочерним узлом
<xsl:strip-space elements="*" />
В качестве альтернативы, вы можете добавить шаблон, соответствующий group
, и явно выбрать только id
узлов
<xsl:template match="Function/group[position()=1]">
<xsl:apply-templates select="Id" />
</xsl:template>