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

Re: Apply for-each-group to a node subset

Subject: Re: Apply for-each-group to a node subset
From: Raman Gupta <rocketraman@xxxxxxxxxxx>
Date: Fri, 21 Sep 2007 11:28:47 -0400
Re:  Apply for-each-group to a node subset
Tony Graham wrote:
> On Fri, Sep 21 2007 08:51:13 +0100, rocketraman@xxxxxxxxxxx wrote:
> ...
> I'm still trying to get my head around what you want to do with your
> template, but the likely reasons that your simplification doesn't work
> are:

I should have provided the output I wanted (obviously ignoring
templates applied to irrelevant nodes). Here it is (basically grouping
all nodes between g1 and g2 into a hierarchical structure).

<r>
  <n1/>
  ...
  <n2/>

  <group>
    <g1/>
    ...
    <g2/>
  </group>

  <group>
    <g1/>
    ...
    <g2/>
  </group>

  <n3/>
  ...
  <n4/>
</r>

I stated in my original email, but didn't emphasize, that there are an
arbitrary number of nodes between g1 - g2, n1 - n2, and n3 - n4 (my
example nodes were badly named).

The point of my first apply templates is to process nodes n1-n2, the
second for-each-group to process the grouped nodes from the first g1
to the last g2, and the last apply templates to process nodes n3-n4.

>  - The preceding-sibling axis is a 'reverse axis' [1], so the
>    immediately preceding sibling is at position 1 in the context for the
>    "[last()]" predicate, not (necessarily) the last position.

I know, but I'm not trying to get the immediately preceding sibling.
Note that my predicate is nested, not outside the prior predicate. In
that apply-templates I'm trying to select all nodes n3-n4.

>  - You are selecting every child element that has a preceding 'g2'
>    sibling (since if there are any preceding 'g2' siblings, there will
>    be a last one of them even when there's only one).
> 
> You may do better with:
> 
>    <xsl:apply-templates
>       select="*[preceding-sibling::*[1][local-name() = 'g2']]"/>
> 
> which selects child elements whose first preceding sibling element (of
> any type) is a 'g2'.

That selects only the first preceding sibling, which results in only
g1 nodes.

This expression works:

    <xsl:apply-templates select="*[preceding-sibling::g2
        and not(following-sibling::g2 or self::g2)]"/>

It selects all nodes that have g2 has a preceding sibling, but not
nodes that have g2 as a following sibling (such as the g1 nodes in all
groups except for the first one) and not g2 itself, which results in
all n3 to n4 nodes.

It works, but I still don't understand why a simple nested predicate
does not work:

     <!-- process nodes after group -->
     <xsl:apply-templates select="*[preceding-sibling::g2[last()]]"/>

The way I read this is: apply templates to all the nodes that have the
LAST g2 as a preceding sibling, which should apply templates to all
nodes n3 to n4.

Cheers,
Raman Gupta

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.