It almost drove me crazy, but I finished. Took me almost 2 hours.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="node() | @*"> <xsl:copy> <xsl:apply-templates select="node() | @*"/> </xsl:copy> </xsl:template> <xsl:template match="list[not(preceding-sibling::*[1][self::list])]"> <ol> <xsl:variable name="selfId" select="generate-id()"/> <xsl:call-template name="recurseItems"/> <xsl:apply-templates select=" following-sibling::list [@level = 1 or not(@level)] [preceding-sibling::*[1][self::list]] [$selfId = generate-id( preceding-sibling::list[not(preceding-sibling::*[1][self::list])][1] ) ] [not(position() = 1)] " mode="recurse"/> </ol> </xsl:template> <xsl:template name="recurseItems"> <xsl:param name="nodes" select="."/> <xsl:variable name="nextStep" select="$nodes/following-sibling::*[1][self::list]"/> <xsl:choose> <xsl:when test="$nodes/@level and ($nodes/@level < $nextStep/@level)"> <li> <xsl:value-of select="$nodes"/> <ol> <xsl:call-template name="recurseItems"> <xsl:with-param name="nodes" select="$nextStep"/> </xsl:call-template> </ol> </li> </xsl:when> <xsl:when test="$nodes/@level and ($nodes/@level > $nextStep/@level)"> <xsl:apply-templates select="$nodes" mode="create"/> </xsl:when> <xsl:when test="$nextStep"> <xsl:apply-templates select="$nodes" mode="create"/> <xsl:call-template name="recurseItems"> <xsl:with-param name="nodes" select="$nextStep"/> </xsl:call-template> </xsl:when> <xsl:when test="not($nextStep)"> <xsl:apply-templates select="$nodes" mode="create"/> </xsl:when> </xsl:choose> </xsl:template> <xsl:template match="list" mode="recurse"> <xsl:call-template name="recurseItems"/> </xsl:template> <xsl:template match="list" mode="create"> <li> <xsl:value-of select="."/> </li> </xsl:template> <xsl:template match="list"/> </xsl:stylesheet>
Applies to a slightly more complex document:
<root> <h1>text</h1> <list level="1">1.1</list> <list level="1">1.2</list> <list level="2">1.2.1</list> <list level="2">1.2.2</list> <list level="3">1.2.2.1</list> <list level="1">1.3</list> <p>text</p> <list>2.1</list> <list>2.2</list> <h2>text</h2> <h1>text</h1> <list level="1">3.1</list> <list level="1">3.2</list> <list level="2">3.2.1</list> <list level="2">3.2.2</list> <list level="3">3.2.2.1</list> <list level="1">3.3</list> <list level="2">3.3.1</list> <list level="2">3.3.2</list> <p>text</p> </root>
He produces this result:
<?xml version="1.0" encoding="UTF-8"?> <root> <h1>text</h1> <ol> <li>1.1</li> <li>1.2 <ol> <li>1.2.1</li> <li>1.2.2 <ol> <li>1.2.2.1</li> </ol> </li> </ol> </li> <li>1.3</li> </ol> <p>text</p> <ol> <li>2.1</li> <li>2.2</li> </ol> <h2>text</h2> <h1>text</h1> <ol> <li>3.1</li> <li>3.2 <ol> <li>3.2.1</li> <li>3.2.2 <ol> <li>3.2.2.1</li> </ol> </li> </ol> </li> <li>3.3 <ol> <li>3.3.1</li> <li>3.3.2</li> </ol> </li> </ol> <p>text</p> </root>
For your sample, it also gives the correct result:
<?xml version="1.0" encoding="UTF-8"?> <root> <h1>text</h1> <ol> <li>num1</li> <li>num2 <ol> <li>sub-num1</li> <li>sub-num2 <ol> <li>sub-sub-num1</li> </ol> </li> </ol> </li> <li>num3</li> </ol> <p>text</p> <ol> <li>num1</li> <li>num2</li> </ol> <h2>text</h2> </root>
source share