selecting a range of nodes

A

Andy Fish

hi,

I am trying to select a range of following siblings using xslt 1.0. consider
the following XML file

<top>
<a1/>
<a2/>
<foo/>
<a3/>
<a4/>
<a5/>
<a6/>
<bar/>
<a7/>
<a8/>
</top>

now, inside this template

<xsl:template match="foo">

I would like to select all the nodes up to the following <bar> (if there are
several <bar>s it would be the next one)

it seems quite simple on the face of it but I can't figure out any way to
get close at the moment

TIA

Andy
 
R

Richard Tobin

Andy Fish said:
I am trying to select a range of following siblings using xslt 1.0. consider
the following XML file

<top>
<a1/>
<a2/>
<foo/>
<a3/>
<a4/>
<a5/>
<a6/>
<bar/>
<a7/>
<a8/>
</top>

now, inside this template

<xsl:template match="foo">

I would like to select all the nodes up to the following <bar> (if there are
several <bar>s it would be the next one)

It's a bit messy. You want the following-siblings of the foo that
have a following-sibling which is the first bar after the foo. So
set a variable $bar to following-sibling::bar[1], and use

following-sibling::*[generate-id(following-sibling::bar[1]) = generate-id($bar)]

In this case generate-id works better than counting the union because some
of the elements may not have a following bar element.

For more complicated examples you might want to use "Muenchian grouping"
(see Google).

-- Richard
 
P

Pavel Lepin

Andy Fish said:
<top>
<a1/>
<a2/>
<foo/>
<a3/>
<a4/>
<a5/>
<a6/>
<bar/>
<a7/>
<a8/>
</top>

now, inside this template

<xsl:template match="foo">

I would like to select all the nodes up to the following
<bar> (if there are several <bar>s it would be the next
one)

The need to do that often indicates a problem with the
design of your XML document.
it seems quite simple on the face of it but I can't figure
out any way to get close at the moment

Read up on generate-id() and current():

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

Note that using keys may result in a significant performance
boost.
 
A

Andy Fish

Thanks to both for the replies

Works a treat

Pavel Lepin said:
Andy Fish said:
<top>
<a1/>
<a2/>
<foo/>
<a3/>
<a4/>
<a5/>
<a6/>
<bar/>
<a7/>
<a8/>
</top>

now, inside this template

<xsl:template match="foo">

I would like to select all the nodes up to the following
<bar> (if there are several <bar>s it would be the next
one)

The need to do that often indicates a problem with the
design of your XML document.
it seems quite simple on the face of it but I can't figure
out any way to get close at the moment

Read up on generate-id() and current():

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

Note that using keys may result in a significant performance
boost.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,194
Latest member
KarriWhitt

Latest Threads

Top