xsl-list
[Top] [All Lists]

Re: [xsl] Grouping by attribute

2009-10-20 06:56:52
Thats perfect. Many thanks!

-Jostein

2009/10/20 Martin Honnen <Martin(_dot_)Honnen(_at_)gmx(_dot_)de>:
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[(_at_)level
= $level]">
     <xsl:choose>
       <xsl:when test="self::headline[(_at_)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/

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--

<Prev in Thread] Current Thread [Next in Thread>