This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Nodes between two nodes with same name


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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]