Это простое, чистое преобразование XSLT 1.0 (без условий, без xsl:for-each
, без передачи параметров, без xsl:element
, без использования печально известного неэффективного //
) :
<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>
применительно к этому XML-документу (предоставленный документ обернут в один верхний элемент):
<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>
дает именно нужный, правильный результат :
<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>
Пояснение : правильное использование xsl:number
и сопоставление шаблонов / шаблонов.