Re: [xsl] Search for efficiency...(building nodes dynamically)

Subject: Re: [xsl] Search for efficiency...(building nodes dynamically)
From: "Ahsan Ali" <doubleletter@xxxxxxxxx>
Date: Sat, 4 Mar 2006 10:30:54 +0400
Thanks Andrew !

This works great (I'm using xsl 1.0 - msxml) !

Best Regards,

Ahsan

On 3/2/06, andrew welch <andrew.j.welch@xxxxxxxxx> wrote:
> On 3/2/06, Ahsan Ali <doubleletter@xxxxxxxxx> wrote:
> > Hi all,
> >
> > I have an XML file of 6588 Airport elements as follows:
> >
> > <apt code="AAF" city="Apalachicola" country="United States"
> > state="FL">Municipal Apt.</apt>
> > ....
> >
> > In an XSLT program, I am processing yet another XML document that has
> > the following format:
> >
> > <availabilitytable>
> >         <avail>
> >                 <origin>XYZ</origin>
> >                 <destination>XYZ</destination>
> >         </avail>
> >
> >         <avail>
> >                 <origin>XYZ</origin>
> >                 <destination>XYZ</destination>
> >         </avail>
> > </availabilitytable>
> >
> > These are an approx of 15-20 'avail' elements.
> >
> > The problem: I have written the XSL sheet in such a way that for every
> > 'origin' and 'destination' element, the
> > <apt> nodeset is traversed to get the airport name of a given code.
> >
> > Therefore, if there are duplicate origins/destinations (which is very
> > probable in my case) there will be unnecessary multiple traversals.
> >
> > So I thought of building a nodeset of all origins/destinations,
> > removing duplicates, and then looking up the <apt> file.
> >
> > The Question(s): Since I will need the result node later on in the XSL
> > file, where do I store it ? And how do I build a result node like this
> > ? If this is not feasible, what is the best method to avoid multiple
> > traversals of such a large tree ?
>
> Use a key:
>
> <xsl:key name="airports-by-code" match="apt" use="@code"/>
>
> then in your <origin> and <destination> templates:
>
> <xsl:template match="origin">
>   <xsl:apply-templates select="key('airports-by-code', .)"/>
>
> You may have to do a little extra work to change the context to the
> correct document - this is done differently between XSLT 1.0 or 2.0
> but it's pretty trivial either way:
>
> For 1.0, you have to change the context node to the airport XML using
> a for-each, keeping track of the value of the origin node:
>
> <xsl:template match="origin">
>   <xsl:variable name="origin" select="."/>
>   <xsl:for-each select="$airportsDoc">
>     <xsl:apply-templates select="key('airports-by-code', $origin)"/>
>
> For 2.0, you can use the 3rd argument of key() to specify the XML that
> should keyed into:
>
> <xsl:template match="origin">
>   <xsl:apply-templates select="key('airports-by-code', ., $airportsDoc)"/>
>
> Another great feature of 2.0!
>
> cheers
> andrew

Current Thread