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>