Re: [xsl] flat xml tree to indent one

Subject: Re: [xsl] flat xml tree to indent one
From: Matthieu Ricaud-Dussarget <matthieu.ricaud@xxxxxxxxx>
Date: Wed, 22 Dec 2010 10:14:45 +0100
Thank you Wendel, this adapted solution is interesting because as you guess, i don't always want to create an element per attribute, this was the "school case". I actually needed to have separated traitment on each attribute. Mickael's solution made exactly what I asked and I had to adapt it. Thanks for doing it ;-)

Regards,
Matt


Le 21/12/2010 18:17, Wendell Piez a icrit :
Hi,

Mike's elegant 2.0 recursive variable processing can also be extended easily to support a more granular mapping of attribute/value combinations to elements, something like this:

<xsl:template match="p[@*]">
<xsl:variable name="temp">
<p>
<xsl:copy-of select="remove(@*, 1)"/>
<xsl:apply-templates select="@*[1]" mode="map-attribute"/>
</p>
</xsl:variable>
<xsl:apply-templates select="$temp"/>
</xsl:template>

<xsl:template match="p[not(@*)]">
<xsl:sequence select="."/>
</xsl:template>

<xsl:template match="@*" mode="map-attribute">
<xsl:element name="{name(.)}">
<xsl:copy-of select="../node()"/>
</xsl:element>
</xsl:template>

<xsl:template match="@style[.='bold']" mode="map-attribute">
<b>
<xsl:copy-of select="../node()"/>
</b>
</xsl:template>

Here's an old XSLT 1.0 precursor:

http://markmail.org/message/nxrz4kk42lr4jxo2


Cheers, Wendell

On 12/21/2010 7:47 AM, Michael Kay wrote:
On 21/12/2010 12:30, Matthieu Ricaud-Dussarget wrote:
Hi all,

This is a grouping question one more time.
It's not actually a grouping problem as commonly understood.

For such an input :


<p foo="foo_att" bar="bar_att" foobar="foobar_att">my text</p>

I'd like such an output :

<p>
<foo><bar><foobar>my text</foobar></bar></foo>
</p>

the order foo/bar/foobar isn't important here.
<foobar><bar><foo>my text</foo></bar></foobar> would also be ok.

This should work for any number of attributes (including none)

You need to process the attributes one at a time, recursively:

<xsl:template match="p[@*]">
<xsl:variable name="temp">
<p>
<xsl:copy-of select="remove(@*, 1)"/>
<xsl:element name="{name(@*[1])}">
<xsl:copy-of select="child::node()"/>
</xsl:element>
</p>
</xsl:variable>
<xsl:apply-templates select="$temp"/>
</xsl:template>

<xsl:template match="p[not(@*)]">
<xsl:sequence select="."/>
</xsl:template>




--
Matthieu Ricaud
IGS-CP
Service Livre numirique

Current Thread