xsl-list
[Top] [All Lists]

Re: [xsl] Apply for-each-group to a node subset

2007-09-21 08:29:16
Tony Graham wrote:
On Fri, Sep 21 2007 08:51:13 +0100, rocketraman(_at_)fastmail(_dot_)fm 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

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