Altova Mailing List Archives
>xsl-list Archive Home
>Thread Prev - [xsl] Improving efficiency of an XPath expression?
Re: [xsl] Improving efficiency of an XPath expression?
Date: 6/7/2002 5:00:00 AM
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]/preceding-sibling::lg | /example/lg[l/@id = $targetid] | /example/lg[l/@id = $targetid]/following-sibling::lg 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]" /> ... select="$lg/preceding-sibling::lg | $lg | $lg/following-sibling::lg" ... 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] /(preceding-sibling::lg | . | following-sibling::lg) You could alternatively use something closer to what you had already: /example/lg[following-sibling::lg/l/@id = $targetid or l/@id = $targetid or preceding-sibling::lg/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 , 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/l/@id | l/@id | following-sibling::lg/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