I. 少し短い XSLT 1.0 ソリューション:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="kUlist" match="unnumberedList"
use="generate-id(preceding-sibling::*
[not(self::unnumberedList)][1]
)"/>
<xsl:template match="/*">
<html>
<xsl:apply-templates select="numberedList[1]" mode="first"/>
</html>
</xsl:template>
<xsl:template match="numberedList" mode="first">
<ol>
<xsl:apply-templates select=". | following-sibling::*"/>
</ol>
</xsl:template>
<xsl:template match="*">
<li><xsl:apply-templates /></li>
</xsl:template>
<xsl:template match=
"unnumberedList
[not(preceding-sibling::*[1][self::unnumberedList])]">
<li>
<ul>
<xsl:apply-templates mode="inUList" select=
"key('kUlist', generate-id(preceding-sibling::*[1]))"/>
</ul>
</li>
</xsl:template>
<xsl:template match="*" mode="inUList">
<li><xsl:value-of select="."/></li>
</xsl:template>
<xsl:template match="unnumberedList"/>
</xsl:stylesheet>
この変換が提供された XML ドキュメントに適用されると、次のようになります。
<xml>
<numberedList>1. Number List 1</numberedList>
<unnumberedList>Child List 1</unnumberedList>
<unnumberedList>Child List 2</unnumberedList>
<unnumberedList>Child List 3</unnumberedList>
<numberedList>2. Number List 2</numberedList>
<unnumberedList>Child List 1</unnumberedList>
<numberedList>3. Number List 3</numberedList>
</xml>
必要な正しい結果が生成されます。
<html>
<ol>
<li>1. Number List 1</li>
<li>
<ul>
<li>Child List 1</li>
<li>Child List 2</li>
<li>Child List 3</li>
</ul>
</li>
<li>2. Number List 2</li>
<li>
<ul>
<li>Child List 1</li>
</ul>
</li>
<li>3. Number List 3</li>
</ol>
</html>
Ⅱ.XSLT 2.0 ソリューション -- I より 30% 短い。
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/*">
<html>
<ol>
<xsl:for-each-group select="*" group-adjacent="name()">
<xsl:apply-templates select="current-group()"/>
</xsl:for-each-group>
</ol>
</html>
</xsl:template>
<xsl:template match="*" mode="#default inUList">
<li><xsl:apply-templates/></li>
</xsl:template>
<xsl:template match=
"unnumberedList[preceding-sibling::*[1][not(self::unnumberedList)]]">
<li>
<ul>
<xsl:apply-templates mode="inUList" select="current-group()"/>
</ul>
</li>
</xsl:template>
<xsl:template match="unnumberedList"/>
</xsl:stylesheet>
この XSLT 2.0 変換を同じ XML ドキュメント (上記) に適用すると、同じ正しい結果が生成されます。
<html>
<ol>
<li>1. Number List 1</li>
<li>
<ul>
<li>Child List 1</li>
<li>Child List 2</li>
<li>Child List 3</li>
</ul>
</li>
<li>2. Number List 2</li>
<li>
<ul>
<li>Child List 1</li>
</ul>
</li>
<li>3. Number List 3</li>
</ol>
</html>