Как показал @DevNull, использовать преобразование идентичности гораздо проще и менее многословно.В любом случае, вот одно из возможных решений с for-each
и без apply-templates
, как вы и просили:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/root">
<root>
<xsl:for-each select="child::node()">
<xsl:choose>
<xsl:when test="position()=last()-1"/>
<xsl:otherwise>
<xsl:copy>
<xsl:copy-of select="@att"/>
<xsl:copy-of select="child::node()"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</root>
</xsl:template>
Примечание об использовании преобразования идентификаторов
Есливаша ситуация на самом деле выглядит так, я имею в виду неизвестное имя элементов, @DevNull не будет работать, и вам нужно что-то более общее, например:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="root/child::node()[position()=last()]|@att2"/>
</xsl:stylesheet>
Это решение будет работать даже с последнимиэлементы e4
или e1000
.