As @DevNull showed, using identity conversion is much simpler and less verbose. Anyway, here is one possible solution with for-each and without apply-templates at your request:
<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>
A Note About Using Identity Conversion
If your situation really looks like this, I mean the unknown element name, @DevNull will not work, and you will need something more general, like this:
<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>
This solution will work even with the latest elements of e4 or e1000 .
source share