xsl-list
[Top] [All Lists]

Re: [xsl] grouping based on string but with child nodes

2008-10-13 12:13:08
Hey! that seems to work.  Thanks also to the other suggestions (and as
always David and Mike).  I thought I had the idea of how to do it
right, it was remembering (how) to use  analyze-string properly that I
was having as a monday-afternoon mental block.

Just to make sure I'm understanding it, a couple questions
interspersed below with my understanding of what it does.

On Mon, Oct 13, 2008 at 16:40, G. Ken Holman
<gkholman(_at_)cranesoftwrights(_dot_)com> wrote:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
               xmlns:dummy="urn:x-Dummy"
               exclude-result-prefixes="dummy"
               version="2.0">

Sticking stuff into a dummy namespace, but really I could use the
namespace of the intended output couldn't I?

<xsl:output indent="yes"/>

<xsl:template match="@*|node()"><!--identity for all other nodes-->
 <xsl:copy>
   <xsl:apply-templates select="@*|node()"/>
 </xsl:copy>
</xsl:template>

 Yup, copy everything we don't match below, makes sense...

<xsl:template match="title">
 <xsl:variable name="separated-titles" as="node()*">
   <xsl:apply-templates mode="separate-titles"/>
 </xsl:variable>

Make a variable called separated-titles which uses a mode to apply the
appropriate templates below.  Does one need to cast it as node()*? I
almost never do this, I guess I'm  a bit sloppy with typing of things

 <xsl:variable name="titles" as="element(title)*">
   <xsl:for-each-group select="$separated-titles"
                       group-starting-with="dummy:dummy">
     <title>
       <xsl:copy-of select="current-group()[not(self::dummy:dummy)]"/>
     </title>
   </xsl:for-each-group>
 </xsl:variable>
 <xsl:copy-of select="$titles"/>
</xsl:template>

Make a variable that does a for-each-group, here cast as
element(title)* which I'm not sure I understand but I'm guessing means
that the output of the variable is required to be zero-or-more title
elements? grouping with groups starting with the dummy:dummy element
maybe before.  And the content is to copy the entire thing but exclude
from that copy the very dummy:dummy that you're grouping by.  nifty!


<xsl:template match="*" mode="separate-titles">
 <xsl:copy-of select="."/>
</xsl:template>

Copy everything in separate-titles mode.

<xsl:template match="text()" mode="separate-titles">
 <xsl:analyze-string select="." regex="\|\|">
   <xsl:matching-substring>
     <dummy:dummy/>
   </xsl:matching-substring>
   <xsl:non-matching-substring>
     <xsl:value-of select="."/>
   </xsl:non-matching-substring>
 </xsl:analyze-string>
</xsl:template>

For every text node inside a title (since this is
mode="separate-titles") use analyze-string to find every escaped ||,
which is fine because we're just handling the text nodes.  In this if
it matches put out the dummy:dummy element we strip out later above,
and if it doesn't match then just put out the text.

Cool. I actually think I understand that at the moment.  Must remember
to use analyze-string on text nodes more....

Many thanks,

-James

--~------------------------------------------------------------------
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>
--~--