This is a simple, pure XSLT 1.0 conversion (no conditional expressions, no xsl:for-each , no parameter passing, no xsl:element , no sadly inefficient // ) :
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:my="my:my" exclude-result-prefixes="my" > <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <my:names> <n>odd</n> <n>even</n> </my:names> <xsl:variable name="vStyles" select="document('')/*/my:names/*"/> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="book/author"> <xsl:variable name="vPos"> <xsl:number level="any" count="book/author|book[not(author)]"/> </xsl:variable> <book style="{$vStyles[$vPos mod 2 +1]}"> <xsl:copy-of select="@*|../node()[not(self::author)]"/> <author-name> <xsl:value-of select="normalize-space()"/> </author-name> </book> </xsl:template> <xsl:template match="book[author]"> <xsl:apply-templates/> </xsl:template> <xsl:template match="book[not(author)]"> <xsl:variable name="vPos"> <xsl:number level="any" count="book/author|book[not(author)]"/> </xsl:variable> <book style="{$vStyles[$vPos mod 2 +1]}"> <xsl:copy-of select="@*|node()"/> <author-name/> </book> </xsl:template> <xsl:template match="book[author]/*[not(self::author)]"/> </xsl:stylesheet>
as applied to this XML document (provided that it is wrapped in one top element):
<t> <book> <title>My book</title> <pages>200</pages> <size>big</size> <author> <name>Smith</name> </author> <author> <name>Wallace</name> </author> <author> <name>Brown</name> </author> </book> <book> <title>Other book</title> <pages>100</pages> <size>small</size> <author>King</author> </book> <book> <title>Pretty book</title> <pages>150</pages> <size>medium</size> </book> </t>
produces exactly the necessary, correct result :
<t> <book style="even"> <title>My book</title> <pages>200</pages> <size>big</size> <author-name>Smith</author-name> </book> <book style="odd"> <title>My book</title> <pages>200</pages> <size>big</size> <author-name>Wallace</author-name> </book> <book style="even"> <title>My book</title> <pages>200</pages> <size>big</size> <author-name>Brown</author-name> </book> <book style="odd"> <title>Other book</title> <pages>100</pages> <size>small</size> <author-name>King</author-name> </book> <book style="even"> <title>Pretty book</title> <pages>150</pages> <size>medium</size> <author-name/> </book> </t>
The explanation . Appropriate use of xsl:number and pattern / pattern matching.
source share