[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: grouping based on string but with child nodes

Subject: Re: grouping based on string but with child nodes
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Mon, 13 Oct 2008 12:47:14 -0400
Re:  grouping based on string but with child nodes
At 2008-10-13 17:12 +0100, James Cummings wrote:
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@xxxxxxxxxxxxxxxxxxxx> 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?

I suppose, but does the use of that element *really* mean what you say it is? Where I needed a dummy element I explicitly called it a dummy element.


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

It changes how the processor looks at the title elements. Without it, $separated-titles has only a single node, that being the root of the temporary tree. By indicating this type then the processor creates a set of nodes instead of a tree of nodes. The set of nodes is important for the way I've written for-each-group ... if it were a tree I would have had to address the child nodes of the tree root.


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

Yes, instead of a single node being the top of a temporary tree.


Mike Kay's advice in his posts has convinced me that typing is so very important. In my XSLStyle documentation methodology I enforce a stylesheet writing rule that mandates every global variable be explicitly typed, otherwise the violation is flagged visibly in the documentation.

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!

Yes ... note that the first group doesn't have a dummy:dummy so you cannot use:


current-group()[position()>1]

... which is what I would have used if *every* group began with a dummy:dummy element. But when using group-starting-with= there may be (as here) a set of nodes not meeting the criterion, therefore the first group doesn't in fact start with the element.

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

Copy everything in separate-titles mode.

Copy every *element* ... this handles the <emph> or any other element. Note that this doesn't process the content, it copies the element and its descendants in their entirety. This allows you to have "||" in the emphasized content because it really is content and not a delimiter between titles.


> <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 fact we are only handling the child text nodes of the original <title>, not descendent text nodes.


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

Yes, you've got a handle on it all, and you were heading in the right direction from the start.


. . . . . . . . . . . . . Ken

--
Upcoming XSLT/XSL-FO hands-on courses:      Wellington, NZ 2009-01
Training tools: Comprehensive interactive XSLT/XPath 1.0/2.0 video
Video sample lesson:    http://www.youtube.com/watch?v=PrNjJCh7Ppg
Video course overview:  http://www.youtube.com/watch?v=VTiodiij6gE
G. Ken Holman                 mailto:gkholman@xxxxxxxxxxxxxxxxxxxx
Crane Softwrights Ltd.          http://www.CraneSoftwrights.com/s/
Male Cancer Awareness Nov'07  http://www.CraneSoftwrights.com/s/bc
Legal business disclaimers:  http://www.CraneSoftwrights.com/legal

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.