[XSL-LIST Mailing List Archive Home]
Re: [xsl] Optimizing preceding-sibling & following-sibling axes (with key()?)
Subject: Re: [xsl] Optimizing preceding-sibling & following-sibling axes (with key()?)|
From: Martynas Jusevicius <martynas.jusevicius@xxxxxxxxx>
Date: Wed, 7 Apr 2010 22:04:51 +0200
I am using XSLT 2, but only learning one of its new features at a time
:) I'm more used to XSLT 1.
I'll try the for-each-group approach. But how would it work with recursion?
What I'm trying to do is to build hierarchical Table of Contents
(which unfortunately can have gaps between heading levels, as it is
not enforced in XHTML that they have to be incremental, therefore h4
can follow h2).
I am using $descendant-headings within a recursive template, this
variable defines the next level of heading elements on which this
template will be applied on. I adapted the generic preceding/following
sibling approach to select elements which are in between of two other
elements, which I had found on this list, I think.
On Wed, Apr 7, 2010 at 9:46 PM, G. Ken Holman
> At 2010-04-07 20:56 +0200, Martynas Jusevicius wrote:
>> I have such a variable definition (quite cumbersome):
>> <xsl:variable name="descendant-headings"
>> select="following-sibling::h:*[self::h:h1 or self::h:h2 or self::h:h3
>> or self::h:h4 or self::h:h5 or self::h:h6][o2e:heading-level(.) >
>> o2e:heading-level(current())][preceding-sibling::h:*[self::h:h1 or
>> self::h:h2 or self::h:h3 or self::h:h4 or self::h:h5 or
>> self::h:h6][o2e:heading-level(.) = o2e:heading-level(current())] is
>> Basically, I need to select all descendant (level-wise, not as in
>> descendant axis) headings for the current() one, meaning all following
>> headings with lower level which go before the next heading one the
>> same level as current(). This expression gives me what I need.
>> o2e:heading-level() function simply extracts the level number from
>> elements name, like 'h3'.
>> Now, I've read multiple times that preceding-sibling/following-sibling
>> are slow. I wonder if this expression could be optimized?
> I'm not sure why you are using that expression at all. It is obvious
> because of the use of a user-defined function that you are running XSLT 2.0
> ... your use-case is the exemplar I use in the classroom for:
> <xsl:for-each-group group-starting-with="...
> ... to infer depth from flatness.
>> I also have a key definition which I use for similar purposes:
>> <xsl:key name="heading-by-level" match="h:h1 | h:h2 | h:h3 | h:h4 |
>> h:h5 | h:h6" use="number(substring-after(local-name(), 'h'))"/>
>> I just can't figure out how combine this key with the sibling axes to
>> get the same result and improve performance, i.e. that instead of
>> traversing the whole document it would be enough to traverse key()
>> values, like in key('heading-by-level', 1 to 6).
>> Does it make sense?
> Maybe for XSLT 1.0, but not that way. I would simply use the preceding
> finding the closest heading and put the generated id of that heading as the
> lookup value. Then when walking through the headings I would find the
> content for that heading from the key table instead of from the axes. It
> was much faster than trying to use the axes.
> But I think you just want to use the XSLT 2.0 grouping approach if you are
> trying to infer something like DocBook (with nested sections) from XHTML
> (with sibling sections).
> I hope this helps.
> . . . . . . . . . . Ken
> XSLT/XQuery training: San Carlos, California 2010-04-26/30
> Principles of XSLT for XQuery Writers: San Francisco,CA 2010-05-03
> XSLT/XQuery training: Ottawa, Canada 2010-05-10/14
> XSLT/XQuery/UBL/Code List training: Trondheim,Norway 2010-06-02/11
> Vote for your XML training: http://www.CraneSoftwrights.com/s/i/
> Crane Softwrights Ltd. http://www.CraneSoftwrights.com/s/
> G. Ken Holman mailto:gkholman@xxxxxxxxxxxxxxxxxxxx
> Male Cancer Awareness Nov'07 http://www.CraneSoftwrights.com/s/bc
> Legal business disclaimers: http://www.CraneSoftwrights.com/legal