Recursion in XSLT is fun

cocoon

Well, recursion is always fun and powerful, isn't it?

If you're into XSLT you might like this one - the problem was converting a flat structure (a wordML text run) in a nested structure as used for formatting in HTML.

<xsl:stylesheet version="1.0" xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="*"> xsl:copy <xsl:copy-of select="@*"/> xsl:apply-templates/ </xsl:copy> </xsl:template>

<xsl:template match="w:r"> <xsl:variable name="styles" select="w:rPr/*"/> <xsl:call-template name="styleProcessor"> <xsl:with-param name="styles" select="$styles"/> <xsl:with-param name="content" select="w:t"/> </xsl:call-template> </xsl:template>

<xsl:template name="styleProcessor"> <xsl:param name="styles"/> <xsl:param name="content"/>

<xsl:variable name="nextStyles" select="$styles[position() > 1]"/>

<xsl:variable name="styleElement"> <xsl:apply-templates select="$styles[1]" mode="styleElement"/> </xsl:variable>

<xsl:element name="{$styleElement}">

<xsl:apply-templates select="$styles[1]" mode="styleAttributes"/>

xsl:choose <xsl:when test="$nextStyles">

<xsl:call-template name="styleProcessor"> <xsl:with-param name="styles" select="$nextStyles"/> <xsl:with-param name="content" select="$content"/> </xsl:call-template> </xsl:when>

xsl:otherwise

<xsl:apply-templates select="$content"/> </xsl:otherwise> </xsl:choose>

</xsl:element> </xsl:template>

<xsl:template match="*" mode="styleElement"> <xsl:value-of select="local-name()"/> </xsl:template>

<xsl:template match="*" mode="styleAttributes"/>

<xsl:template match="w:lang" mode="styleAttributes"> <xsl:attribute name="lang"> <xsl:value-of select="@w:val"/> </xsl:attribute> </xsl:template>

<xsl:template match="w:t"> xsl:apply-templates/ </xsl:template>

</xsl:stylesheet>