Re: [xsl] Optimizing preceding-sibling & following-sibling axes (with key()?)

Subject: Re: [xsl] Optimizing preceding-sibling & following-sibling axes (with key()?)
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Wed, 07 Apr 2010 15:46:42 -0400
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(.) &gt;
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())][1] is
current()]"/>

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 axis 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

Current Thread