XSLT: tips and tricks: how to generate node1, node2, …, nodeN

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>

Gennady Kim

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s