Re: [xsl] Grouping by attribute

Subject: Re: [xsl] Grouping by attribute
From: Syd Bauman <Syd_Bauman@xxxxxxxxx>
Date: Tue, 20 Oct 2009 23:17:44 -0400
The following does what I think you've asked for (plus a bit more).
There are probably better ways to do it, but ...

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                version="1.0">

  <!-- Match root and apply templates to whatever comes along -->
  <!-- (Likely to be a PI or two, some comments, and the root -->
  <!-- element.) -->
  <xsl:template match="/">
    <xsl:apply-templates select="node()"/>
  </xsl:template>
  
  <!-- Identity transform for most stuff: -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  
  <!-- But for a <p> that has a child <quote>, process -->
  <!-- the nodes *without* copying the <p> itself to the -->
  <!-- output yet. -->
  <xsl:template match="p[quote]">
    <xsl:apply-templates select="node()"/>
  </xsl:template>

  <!-- For text nodes that are a direct child of a <p> -->
  <!-- element ... -->
  <xsl:template match="text()[parent::p]">
    <!-- ... generate a <p> element just for this text node. -->
    <p>
      <!-- If this is the first child text node of the parent <p>, -->
      <!-- then copy over the parent <p> attributes to this output -->
      <!-- <p>. -->
      <xsl:if test="position()=1">
        <xsl:copy-of select="../@*"/>
      </xsl:if>
      <!-- Copy over the actual text (remember, this is a text -->
      <!-- node we've matched). You may want to use normalize- -->
      <!-- space() here to make the output XML prettier, pres- -->
      <!-- uming you're not interested in the details of white -->
      <!-- space in your text nodes. -->
      <xsl:value-of select="."/>
    </p>
  </xsl:template>

  <!-- Copyright 2009 Syd Bauman, available for anyone to copy -->
  <!-- and use in whole or part under the terms of the Creative -->
  <!-- Commons Attribution-Share Alike 3.0 United States License, -->
  <!-- http://creativecommons.org/licenses/by-sa/3.0/us/. -->

</xsl:stylesheet>

> <p>
>     text
>     <quote>text</quote>
>     text
>     <quote>text</quote>
>     text
> </p>
> 
> to
> 
> <p>text</p>
> <quote>text</quote>
> <p>text</p>
> <quote>text</quote>
> <p>text</p>

Current Thread