Re: [xsl] Creating Nested Structure Based on Attributes

Subject: Re: [xsl] Creating Nested Structure Based on Attributes
From: Abel Braaksma <>
Date: Mon, 19 Mar 2007 12:11:56 +0100
Jeff Sese wrote:

<inline font-style="italic" font-variant="small-caps" font-weight="bold" vertical-alignment="superscript">text</inline>

Hi Jeff,

David Carlisle already showed you how to do it in XSLT 1.0 with mode switching. I don't know if you have the possibility to use XSLT 2.0, but here's a solution that does the same in XSLT 2.0, with the help of a little function that turns any range of attributes into a hierarchical node list, making it easier to use with matching templates. It's perhaps a bit non-conventional, but it keeps your code pretty tight.

Output from your source is equal to the requested output.

Happy coding!

-- Abel Braaksma

<xsl:stylesheet xmlns:f="http://function"; xmlns:xsl=""; version="2.0">

<xsl:output indent="yes" />

<xsl:template match="inline">
<xsl:apply-templates select="f:attr-to-nodes-hier(attribute::*, text())" />

<!-- result from f:attr-to-nodes-hier -->
<xsl:template match="attr">
<emphasis format="{@value}">
<xsl:apply-templates select="node()" />
<!-- result from f:attr-to-nodes-hier -->
<xsl:template match="attr[@name = 'vertical-alignment']">
<xsl:apply-templates select="node()" />
<xsl:function name="f:attr-to-nodes-hier" as="node()*">
<xsl:param name="attributes" as="attribute()*" />
<xsl:param name="text" as="text()" />
<xsl:if test="$attributes">
<attr name="{$attributes[1]/name()}" value="{$attributes[1]}">
<xsl:copy-of select="f:attr-to-nodes-hier($attributes[position() > 1], $text)" />
<xsl:if test="empty($attributes)">
<xsl:sequence select="$text" />
</xsl:if> </xsl:function>

Current Thread