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

Re: Nodes between two nodes with same name

Subject: Re: Nodes between two nodes with same name
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Sat, 19 Aug 2000 11:22:53 +0100
xpath select between two nodes
Jonas,

>What I need is to select nodesets including nodes <tag> and
>all other till next <tag> node.

With any grouping question like this, there are two stages: identify the
first nodes in the group, and identify the rest of the nodes in the group
from that first one.

In your case it's easy to identify the first node in the group: they're the
tag elements.  So, if you just process the 'tag' elements, then you can
process the rest of the elements you want within that template:

<xsl:template match="body">
  <xsl:apply-templates select="tag" />
</xsl:template>

<xsl:template match="tag">
  ...
</xsl:template>

It's identifying the rest of the nodes that's the difficulty.  So what is
it that identifies the group?  You want all the nodes that are before the
next tag in the list.  So, for all the nodes in the group, the next 'tag'
element is going to be the same element.

You can get the 'next tag element' with the XPath:

  following-sibling::tag[1]

And you can get the next elements (of any kind) with the XPath:

  following-sibling::*

Now you want a predicate that can select, from all those elements, those
elements whose next 'tag' element is the same as the next 'tag' element for
the current 'tag' element.  Within the 'tag' template, the 'tag' element is
the current node, so the *next* tag element can always be identified with:

  current()/following-sibling::tag[1]

And comparing nodes can be done with generate-id(), giving us the final XPath:

  following-sibling::*[generate-id(following-sibling::tag[1]) = 
                       generate-id(current()/following-sibling::tag[1])]

So here is a template that groups your input just by putting each of the
groups (separated by the 'tag' elements) inside 'group' elements:

<xsl:template match="tag">
 <group>
   <xsl:copy-of select="
   following-sibling::*[generate-id(following-sibling::tag[1]) = 
                        generate-id(current()/following-sibling::tag[1])]
       " />
  </group>
</xsl:template>

This works in SAXON and Xalan.

I hope that this helps,

Jeni

Jeni Tennison
http://www.jenitennison.com/


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


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.