Subject: Re: Grouping by attribute
From: Jostein Austvik Jacobsen <josteinaj@xxxxxxxxx>
Date: Tue, 20 Oct 2009 12:56:20 +0200
|
Thats perfect. Many thanks!
-Jostein
2009/10/20 Martin Honnen <Martin.Honnen@xxxxxx>:
> Jostein Austvik Jacobsen wrote:
>>
>> Now, what if I want to replace all <p>-tags with <para>, and change
>> the namespace of all nodes to "foo"?
>
> If the input is
>
> <document>
> <metaData>
> <title>Title</title>
> <publisher>Publisher</publisher>
> </metaData>
> <contentSection>
> <p>text</p>
>
> <headline level="2">Headline</headline>
> <p>text</p>
> <p>text</p>
>
> <headline level="2">Section</headline>
> <p>text</p>
> <pagenum id="page2"/>
> <p>text</p>
> <headline level="3">Subsection</headline>
> <p>text</p>
>
> <headline level="2">Section</headline>
> <p>text</p>
> <p>text</p>
> </contentSection>
> </document>
>
> then this stylesheet
>
> <xsl:stylesheet
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
> version="2.0"
> xmlns:xs="http://www.w3.org/2001/XMLSchema"
> xmlns:mf="http://example.com/2009/mf"
> xmlns="http://example.com/foo"
> exclude-result-prefixes="xs mf">
>
> <xsl:output indent="yes"/>
> <xsl:strip-space elements="*"/>
>
> <xsl:function name="mf:group" as="node()*">
> <xsl:param name="nodes" as="node()*"/>
> <xsl:param name="level" as="xs:integer"/>
> <xsl:for-each-group select="$nodes" group-starting-with="headline[@level
> = $level]">
> <xsl:choose>
> <xsl:when test="self::headline[@level = $level]">
> <xsl:element name="level{$level}">
> <xsl:element name="h{$level}">
> <xsl:value-of select="."/>
> </xsl:element>
> <xsl:sequence select="mf:group(current-group() except ., $level
+
> 1)"/>
> </xsl:element>
> </xsl:when>
> <xsl:otherwise>
> <xsl:apply-templates select="current-group()"/>
> </xsl:otherwise>
> </xsl:choose>
> </xsl:for-each-group>
> </xsl:function>
>
> <xsl:template match="@* | node()">
> <xsl:copy>
> <xsl:apply-templates select="@* | node()"/>
> </xsl:copy>
> </xsl:template>
>
> <xsl:template match="document">
> <xsl:variable name="v1" xmlns="">
> <headline level="1"><xsl:value-of select="metaData/title"/></headline>
> <xsl:copy-of select="contentSection/node()"/>
> </xsl:variable>
> <body>
> <xsl:sequence select="mf:group($v1/node(), 1)"/>
> </body>
> </xsl:template>
>
> <xsl:template match="p">
> <para>
> <xsl:apply-templates select="@* | node()"/>
> </para>
> </xsl:template>
>
> </xsl:stylesheet>
>
> creates the following output:
>
> <body xmlns="http://example.com/foo">
> <level1>
> <h1>Title</h1>
> <para>text</para>
> <level2>
> <h2>Headline</h2>
> <para>text</para>
> <para>text</para>
> </level2>
> <level2>
> <h2>Section</h2>
> <para>text</para>
> <pagenum xmlns="" id="page2"/>
> <para>text</para>
> <level3>
> <h3>Subsection</h3>
> <para>text</para>
> </level3>
> </level2>
> <level2>
> <h2>Section</h2>
> <para>text</para>
> <para>text</para>
> </level2>
> </level1>
> </body>
>
> --
>
> Martin Honnen
> http://msmvps.com/blogs/martin_honnen/
|