Re: [xsl] filtering on following-sibling axis

Subject: Re: [xsl] filtering on following-sibling axis
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Tue, 20 Nov 2001 10:23:47 +0000
Hi Don,

> from the context of <section type="subsection"> I need to access all
> the following sibling sections up to the next <section
> type="subsection">. Of course I can get them all with the expression
> 'following-sibling::section', and exclude the following sections
> that have the attribute type="subsection" by adding the predicate
> [not(@type='subsection')], but I'm unable to write a filter that
> stops accessing the following siblings at the next subsection.

You can look at it this way: you want to get all the following section
elements whose type is not 'subsection' and whose closest preceding
section with a type of 'subsection' is the current section. This won't
be true for any section elements after the following 'subsection'
because *their* closest preceding 'subsection' will be the next one.

To put that in an XPath: all the following section elements:

  following-sibling::section

whose type is not 'subsection':

  following-sibling::section[@type != 'subsection']

and whose closest preceding section with a type of 'subsection':

  following-sibling::section[@type != 'subsection']
    [... preceding-sibling::section[@type = 'subsection'][1] ...]

is the same as the current section:

  following-sibling::section[@type != 'subsection']
    [generate-id(preceding-sibling::section[@type = 'subsection'][1])
     = generate-id(current())]

If you have several headings in your book, you might need to expand
the interesting preceding siblings to headings as well:

  following-sibling::section[@type != 'subsection']
    [generate-id(preceding-sibling::section
                   [@type = 'subsection' or @type = 'heading'][1])
     = generate-id(current())]

I'd usually put this in a key, so that you associate each subsection
generated ID with its sections:

<xsl:key name="sections"
   match="section[@type != 'subsection' and @type != 'heading']"
   use="generate-id(preceding-sibling::section
                      [@type = 'section' or @type = 'heading'][1])" />

Then you could just do:

  key('sections', generate-id())

to get all the relevant following sections.
     
I hope that helps,

Jeni

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


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


Current Thread