This time let me show you how to generate several similar XML elements like name1, name2, name3, …, nameN.
Input:
<?xml version="1.0" encoding="utf-8"?> <names> <name>John Smith</name> <name>Bill Murray</name> <name>Anne Williams</name> <name>Henry Ford</name> </names>
Expected output:
<?xml version="1.0" encoding="utf-8"?> <root> <NAME1>John Smith</NAME1> <NAME2>Bill Murray</NAME2> <NAME3>Anne Williams</NAME3> <NAME4>Henry Ford</NAME4> </root>
Almost always developers are trying to create XSLT like this:
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <root> <xsl:if test="names/name[1]"> <NAME1> <xsl:value-of select="names/name[1]"/> </NAME1> </xsl:if> <xsl:if test="names/name[2]"> <NAME2> <xsl:value-of select="names/name[2]"/> </NAME2> </xsl:if> ... <xsl:if test="names/name[N]"> <NAMEN> <xsl:value-of select="names/name[N]"/> </NAMEN> </xsl:if> </root> </xsl:template> </xsl:stylesheet>
But there is a short and elegant way:
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <root> <xsl:for-each select="names/name"> <xsl:element name="{concat('NAME', position())}"> <xsl:value-of select="."/> </xsl:element> </xsl:for-each> </root> </xsl:template> </xsl:stylesheet>