RE: [xsl] xsl:key on part of a document in XSLT2.0?

Subject: RE: [xsl] xsl:key on part of a document in XSLT2.0?
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Tue, 31 Oct 2006 10:14:53 -0000
In XSLT 2.0 a key is still defined over a whole document, but you can search
for matches within a part of the document using the third argument to the
key() function:

key('k', 'xyz', $element)

searches for nodes with key value 'xyz' within the subtree rooted at
$element.

An alternative is to use Saxon-SA: this should (I haven't checked it
specifically) spot that your current code as written can be optimized by
creating a local index, and do the work for you.

Michael Kay
http://www.saxonica.com/ 


> -----Original Message-----
> From: len feremans [mailto:lenferemans@xxxxxxxxxxx] 
> Sent: 31 October 2006 09:37
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] xsl:key on part of a document in XSLT2.0?
> 
> Hi,
> 
> I am writing XSLT 1.0 stylesheets over a year now and was 
> wondering if the following is possible in XSLT 2.0: Applying 
> a key to only part of a document.
> 
> For example:
> Let's say I do a for-each on each child of a node "$node1" 
> and then check if a "$node2" has any child with the same id...
> 
> <xsl:template name="compare">
> 		<xsl:param name="node1"/>
> 		<xsl:param name="node2"/>
> 		<xsl:for-each select="$node1/e">
> 			<xsl:variable name="id1" select="@id"/>
> 			<xsl:variable name="n2" 
> select="$node2/e[@id = $id1]"/> //can be slow
> 			//do something with node2
>                 </xsl:for-each>
> </xsl:template>
> 
> Now this code can be quite slow if there are thousands of 
> nodes under $node2 or $node1.
> The complexity would be O(N*K) where N = number of children 
> of $node1 and K = number of children of $node2. If I could 
> use a key then complexity could be O(N*log(K)). xsl:key would 
> be also very usefull if it could be created dynamically 
> inside a template... The code could look something like this:
> <xsl:template name="compare">
> 		<xsl:param name="node1"/>
> 		<xsl:param name="node2"/>
>                 <xsl:key name="nodes" match="$node2/e" use="@id"/>
> 		<xsl:for-each select="$node1/e">
> 			<xsl:variable name="id1" select="@id"/>
> 			<xsl:variable name="n2" 
> select="key('nodes',$id1)"/> //fast
> 			//do something with node2
>                 </xsl:for-each>
> </xsl:template>
> 
> Of course I can use extension functions to implement my own 
> key (using java.lang.Map), but is there any other solution 
> for this common problem?
> 
> greetings,
> Len Feremans
> 
> _________________________________________________________________
> Get today's hot entertainment gossip
> http://movies.msn.com/movies/hotgossip?icid=T002MSN03A07001

Current Thread