Wrox Programmer Forums
Go Back   Wrox Programmer Forums > XML > XSLT
|
XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old July 18th, 2009, 05:07 AM
Authorized User
 
Join Date: Jul 2009
Posts: 23
Thanks: 5
Thanked 0 Times in 0 Posts
Default key() not working within variable defined as temporary document

Hello - I'm completely stumped trying to figure this one out so any help would be much appreciated.

I'm trying to do a transformation in two steps. In the first step, I create a variable Var1 based on data in an xml document by manually adding in some elements with attribute values from nodes in the xml document (if a certain condition is satisfied) as well as by using copy-of on some elements in the xml document (if the condition is not satisfied). Thus Var1 is a temporary document (I'm not using "select" to define it). This part works fine and the output (value of Var1) looks good.

In the second step, I create another variable Var2, which goes thru each element in Var1 and if a certain condition is true, a lookup is performed using the key() and for each element returned by the key() function, some logic is performed to create more elements. This part isn't working as expected. The pseudo-code for Var2 looks something like:

Var2=
For-each select=Var1/elementname
For-each select=key(x,y)
Blah

Here's the problem: the key(x,y) doesn't return anything when executed within this nested for-each. To make sure it wasn't something silly, I hardcoded the x and y and when this exact same key() is executed outside of this nested for-each, it works fine.

Now, here's the weird part: if I replace Var1/elementname in the pseudo-code above with another variable Var0 that's not a temporary document but is created using a select (a direct reference to nodes in the original xml document), the key() function works as expected. To eliminate the second for-each as a suspect, I took out the for-each over key() and put in a copy-of as follows:

Var2=
For-each select=Var1/elementname
copy-of select=key(x,y)

This also doesn't work but again if I replace Var1 with Var0, it works fine. Btw, if I output the value of some attribute of elementname within the for-each loop above, it does show correctly so it leads me to believe that the value of Var1 is OK. Not sure why the key() function isn't working within a for-each over a variable that's a temporary document that's created within the stylesheet but works fine within a for-each over a variable that's not a temporary document.. is this a restriction or am I doing something wrong?

Thanks!
NG
 
Old July 18th, 2009, 05:48 AM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

Please state whether you use XSLT 1.0 or 2.0. With XSLT 1.0 you would have a result tree fragment in your variable and you can't do much with result tree fragments other than doing xsl:copy-of or taking the string value. If you wanted to do XPath or key on a result tree fragment you would first need to convert it into a node-set with the help of an extension function like exsl:node-set.
Other than that guess it is hard to tell, consider to show us the real XSLT code you have and not some pseudo code.
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
 
Old July 18th, 2009, 06:14 AM
Authorized User
 
Join Date: Jul 2009
Posts: 23
Thanks: 5
Thanked 0 Times in 0 Posts
Default

Sorry, I forgot to mention, I'm using XSLT 2.0. Below is the code for Var1 and Var2:

Code:
	<xsl:variable name="Var1">
		<xsl:for-each select="$Var0">
			<xsl:variable name="currentnode" select="."></xsl:variable>
			<xsl:choose>
				<xsl:when test="contains(@who,'Group')">
					<xsl:for-each select="key('group-dss',tokenize(@who,'Group:')[2])">
					<rule><xsl:copy-of select="$currentnode/@* except @who"/><xsl:attribute name="who"><xsl:value-of select="@id"/></xsl:attribute> 
					</rule>
					</xsl:for-each>
				</xsl:when>
				<xsl:otherwise>
					<xsl:copy-of select="$currentnode"/>
				</xsl:otherwise>
			</xsl:choose>
		</xsl:for-each>
	</xsl:variable>



	<xsl:variable name="Var2">
		<xsl:for-each select="$Var1/rule">
			<xsl:value-of select="@id"/>
			<xsl:copy-of select="key('group-ass','Group1')"/> 
		</xsl:for-each>
	</xsl:variable>
 
Old July 18th, 2009, 06:25 AM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

Keys are created for each document. Inside the for-each select="$Var1/rule" the key function looks for nodes in the temporary document the rule elements belong to. If that is not what you want then you need to pass in the document node you want to look in as the third argument of the key function e.g.
Code:
<xsl:variable name="main-doc" select="/"/>
    <xsl:variable name="Var2">
        <xsl:for-each select="$Var1/rule">
            <xsl:value-of select="@id"/>
            <xsl:copy-of select="key('group-ass','Group1', $main-doc)"/> 
        </xsl:for-each>
    </xsl:variable>
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
The Following User Says Thank You to Martin Honnen For This Useful Post:
baseliner (July 18th, 2009)
 
Old July 18th, 2009, 01:26 PM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

I think the important point to note is that the key() function always searches the tree that contains the context node. If you want to search a different document, then in 2.0 you can provide its root node as the third argument to the function.
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
The Following User Says Thank You to mhkay For This Useful Post:
baseliner (July 18th, 2009)
 
Old July 18th, 2009, 03:42 PM
Authorized User
 
Join Date: Jul 2009
Posts: 23
Thanks: 5
Thanked 0 Times in 0 Posts
Default

Thank you so much Martin and Michael. There was no way I was going to figure this one out myself! I now see this third parameter for key() mentioned on page 378 of Michael's book.. :) Thanks again!





Similar Threads
Thread Thread Starter Forum Replies Last Post
variable not defined error? SKhna ASP.NET 2.0 Basics 1 April 1st, 2008 05:48 AM
TAB KEY working together KEY PRESS event thomaz C# 4 August 20th, 2006 02:47 PM
Crystal Report 8.0 - Working with Temporary Tables deebeedee VB How-To 0 July 27th, 2006 07:30 AM
Compile Error: Variable not defined Fin Excel VBA 0 February 1st, 2006 01:45 PM
Unable to open registry key 'Temporary p2ptolu Classic ASP Databases 3 March 7th, 2005 06:49 AM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.