[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

RE: [xsl] Grouping immediate follow sibling

Subject: RE: [xsl] Grouping immediate follow sibling
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Tue, 1 Feb 2005 00:06:56 -0000

> I receive XML similar to that shown below:
> <bodyFrag>
> 	<p>title</p>
> 	<ProgAbs>some text</ProgAbs>
> 	<ProgAbs>More text</ProgAbs>
> 	<ProgAbs>Even more</ProgAbs>
> 	<p>Paragraph</p>
> 	<p>Beispiel:</p>
> 	<ProgAbs>some text</ProgAbs>
> 	<ProgAbs>More text</ProgAbs>
> 	<ProgAbs>Even more</ProgAbs>
> </bodyFrag>
> I need to process it as follows:
> 	1. When I see a <p> containing 'title', output it in 
> some way. (I
> can do this part).

A description of the processing that starts "When I see" is not a good place
to start. It suggests you're thinking in terms of sequential processing.

> 	2, Select only the immediately following <ProgAbs> 
> sibling elements.
> I.e. the 3 ProgAbs elements with content immediately following the <p>
> element selected in 1 above.
> Using 'following-sibling::ProgAbs' gives me all the siblings 
> of that name,
> as it should. I just need to know how to construct an 
> expression to select
> only those <ProgAbs> that follow on immendiately after the 
> <p> element.

In XSLT 2.0 you can do this with for-each-group.

In 1.0 there are two main approaches: one is to use
generate-id(preceding-sibling::p[1]) as a grouping key for the ProgAbs
elements, and then use Muenchian grouping. The other is to use head-tail
recursion on the sequence of siblings: so you call a template passing the
full list of siblings as a parameter, this then calls itself to process the
elements after the first if there's another ProgAbs, or returns if there

Michael Kay

Current Thread