|
Subject: Re: [xsl] Improving efficiency of an XPath expression? From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx> Date: Fri, 7 Jun 2002 13:50:27 +0100 |
Hi Michael,
> Now the challenge: given the id attribute value of any one <l>, find
> an XPath expression that will efficiently select a node-set
> containing only: the <lg> that immediately precedes the one where
> the <l> concerned is found, plus the <lg> that is the parent of that
> <l> and the <lg> that immediately follows the one that is the parent
> of the <l> specified. (i.e. "L2063" as input id would return
> precisely the three <lg> elements in the example.)
Assuming that there's only one l with a particular id, try something
like:
/example/lg[l/@id = $targetid][1]/preceding-sibling::lg[1] |
/example/lg[l/@id = $targetid][1] |
/example/lg[l/@id = $targetid][1]/following-sibling::lg[1]
Or, if you can, store the lg that contains the relevant l element in a
variable:
<xsl:variable name="lg" select="/example/lg[l/@id = $targetid][1]" />
... select="$lg/preceding-sibling::lg[1] |
$lg |
$lg/following-sibling::lg[1]" ...
In XPath 2.0, you'd be able to use a general step instead of a
variable, and still get the benefit of only finding the relevant lg
once:
/example/lg[l/@id = $targetid][1]
/(preceding-sibling::lg[1] | . | following-sibling::lg[1])
You could alternatively use something closer to what you had already:
/example/lg[following-sibling::lg[1]/l/@id = $targetid or
l/@id = $targetid or
preceding-sibling::lg[1]/l/@id = $targetid]
but that would mean going through all the lg elements in the document
rather than stopping at the one that contains the relevant l element.
The important things for efficiency here are:
- avoidance of the descendant axis -- step down the lg elements
rather than using //
- using [1], so that the processor only has to make one step rather
than collecting *all* the lg elements and preceding/following
siblings
If you're doing this multiple times in the same transformation, then
setting up a key so that you can quickly find the relevant lg by the
ids of its l elements would be a good idea:
<xsl:key name="lgs" match="lg"
use="preceding-sibling::lg[1]/l/@id |
l/@id |
following-sibling::lg[1]/l/@id" />
and then just use:
key('lgs', $targetid)
Cheers,
Jeni
---
Jeni Tennison
http://www.jenitennison.com/
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
| Current Thread |
|---|
|
| <- Previous | Index | Next -> |
|---|---|---|
| [xsl] Improving efficiency of an XP, Michael Beddow | Thread | Re: [xsl] Improving efficiency of a, Michael Beddow |
| Re: [xsl] Variable containing tree, Jeni Tennison | Date | Re: [xsl] Improving efficiency of a, David Carlisle |
| Month |