This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
RE: Improving efficiency of an XPath expression?
- From: "Michael Kay" <michael dot h dot kay at ntlworld dot com>
- To: <xsl-list at lists dot mulberrytech dot com>
- Date: Fri, 7 Jun 2002 14:39:45 +0100
- Subject: RE: [xsl] Improving efficiency of an XPath expression?
- Reply-to: xsl-list at lists dot mulberrytech dot com
Here's an XPath 2.0 solution (you didn't say it had to be XPath 1.0):
//l[@id=$targetid]/../(.|preceding-sibling::lg[1]|following-sibling::lg[
1])
I don't see any prizes for doing it in one XPath expression so with XSLT
1.0 I would do much the same:
<xsl:variable name="x" select="//l[@id=$targetid]/.."/>
<xsl...
select="$x|$x/preceding-sibling::lg[1]|$x/following-sibling::lg[1]">
And even that's doing it with one hand tied behind your back - it would
run much faster using keys.
Michael Kay
Software AG
home: Michael.H.Kay@ntlworld.com
work: Michael.Kay@softwareag.com
> -----Original Message-----
> From: owner-xsl-list@lists.mulberrytech.com
> [mailto:owner-xsl-list@lists.mulberrytech.com] On Behalf Of
> Michael Beddow
> Sent: 07 June 2002 13:13
> To: XSL-list@lists.mulberrytech.com
> Subject: [xsl] Improving efficiency of an XPath expression?
>
>
> I have a document that consists of several thousand <lg>
> elements each with varying numbers of <l> children. A
> simplified extract looks like this:
>
> <example>
>
> <lg id="G0065">
> <l id="L0258">Putois li aynel afraie</l>
> <l id="L0259">Gopil cleye, thesson traie</l>
> <l id="L0260">Quant li venour li quer praie.</l>
> </lg>
>
> <lg id="G0066">
> <l id="L0261">Ouwe jaungle, jars agroile</l>
> <l id="L0262" >Ane en mareis jaroile</l>
> <l id="L0263" >Mes il i ad jaroil e garoile</l>
> <l id="L0264">La difference dire vous voile:</l>
> </lg>
>
> <lg id="G0067">
> <l id="L0265">Li ane jaroile en rivere</l>
> <l id="L0266">Si hom de falcoun la quere,</l>
> <l id="L0267">Mes devant un vile en guere</l>
> <l id="L0268">Afichom le garoil en tere</l>
> </lg>
>
> </example>
>
> 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.)
>
> Its the "efficiently" bit that's got me stuck. (NB because
> the number of <l>s per <lg> is variable, there's no algorithm
> to derive the id's of the parent, preceding and following
> <lg>s from a given <l>'s id)
>
> I can do it OK with
>
> select = '(//lg[following-sibling::lg/l/@id="$targetid"][last()] |
> //lg[l/@id="$targetid"]) |
> //lg[preceding-sibling::lg/l/@id="$targetid"][1])'
>
> (hope I pasted that all right) but understandably enough even
> the zippy libsxlt/libxml-2 takes its time over that one.
>
> In practice (since I'm doing this in a sequence of
> server-side pipes) it much faster to select simply on
> '//lg[l/@id="$targetid"]' to get the parent node, then parse
> out the id of that node, derive the ids of its preceding and
> following siblings, go back in again to pull them out
> separately, then concatenate the results for further processing.
>
> But can any resident wizard give me a better XPath expression
> that will still grab my target set in one go, only faster
> than my offering above?
>
> Michael
> ---------------------------------------------------------
> Michael Beddow http://www.mbeddow.net/
> XML and the Humanities page: http://xml.lexilog.org.uk/
> The Anglo-Norman Dictionary http://anglo-norman.net/
> ---------------------------------------------------------
>
>
> XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
>
>
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list