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 |