Microsoft Knowledge Base Email Alertz

KBAlertz.com: (324033) - The position() and last() XPath functions are ignored when you use them directly as XSLT function (standard, script, and extension function) arguments in XPath query expressions that are used in XSLT style sheets.

Receive Microsoft Knowledge Base articles by E-Mail?

Every night we scan the Microsoft Knowledge Base. If technologies you're interested in are updated, we'll send you an e-mail. You only get one e-mail a day, and only when new articles are added.

Click here to create a
FREE account
Already have an account?
[Click here to Login]

Search KbAlertz

Advanced Search

Webmasters
Put kbAlertz on your website.
[ Click Here for more! ]





ASP.NET 2.0 Web Hosting with SQL 2005: Click Here!
Discount ASP.NET Hosting


Bug Tracking Software
For bug tracking software or defect tracking software or issue tracking software, visit Axosoft.


Community Site



We Send hundreds of thousands of emails using ASP.NET Email



Expert Web Design & Graphic Design
Design44.com




Mentioned In








Microsoft Knowledge Base Article

This article contents is Microsoft Copyrighted material.
©2005-©2007 Microsoft Corporation. All rights reserved. Terms of Use | Trademarks




BUG: Position() and Last() XPath Functions Are Ignored When You Use Them as XSLT Function Arguments

Article ID:324033
Last Review:July 16, 2004
Revision:3.2
This article was previously published under Q324033
On This Page

SYMPTOMS

The position() and last() XPath functions are ignored when you use them directly as XSLT function (standard, script, and extension function) arguments in XPath query expressions that are used in XSLT style sheets.

Back to the top

CAUSE

The XPath processor executes the XSLT functions before it sets the context of the position() and last() XPath functions.

Back to the top

RESOLUTION

Use XSLT variables to store the values that these functions return. You can then use the XSLT variables as the XSLT function arguments in XPath query expressions that are used in the style sheet.

Back to the top

STATUS

Microsoft has confirmed that this is a problem in the Microsoft products that are listed at the beginning of this article.

Back to the top

MORE INFORMATION

Note that this problem does not occur when the position() and last() functions are used in a predicate in an expression that is supplied as an XSLT function argument.

Back to the top

Steps to Reproduce the Behavior

1.In Microsoft Visual Studio .NET, create a new Visual Basic .NET Console Application project.
2.Use the following code to create and add an XML document named Repro.xml to the project:
<Data>
	<value>1</value>
	<value>2</value>
	<value>3</value>
	<value>78</value>
	<value>5</value>
	<value>88</value>
	<value>7</value>
</Data>
					
3.Use the following code to create and add an XSLT style sheet named Repro.xsl to the project. Study the inline comments to understand the functionality of the code in the style sheet:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:key name="Values" match="value" use="."/>

    <xsl:template match="Data">
	<Data>
	        
	<!-- 

	Use the XSLT key() function to identify and output 
	value elements whose value matches their position in the source XML. 

	The following will not work because the position() function is supplied 
	directly as an argument of the key() function. 

	--> 
	<ValuesThatMatchPosition>        
		<xsl:for-each select="value">
       		    <xsl:if test="key('Values',position())">
		            <value><xsl:value-of select="."/></value>   		    
		   </xsl:if>	   
		</xsl:for-each>	
    	</ValuesThatMatchPosition>

	<!-- 

	The position() function works correctly when used in a predicate in an expression supplied
	as an XSLT function (the format-number function is used in this sample) argument. 

	The select expression in the following line will retrieve the value of the 3rd value element 
	in the source XML.

	--> 
	
	<Position3Value><xsl:value-of select="format-number(value[position()=3],'0')"/></Position3Value>	
        
	</Data>
    </xsl:template>       

</xsl:stylesheet> 
					
4.Paste the following code in the Sub Main() procedure in Module1.vb to execute the XSLT transformation by applying Repro.xsl to Repro.xml:
 Dim transform As New System.Xml.Xsl.XslTransform()
 transform.Load("..\Repro.xsl")
 transform.Transform("..\Repro.xml", "..\output.xml")
 Console.WriteLine("Done")
 Dim response As String = Console.ReadLine
					
5.Save and run the project. The code in the Sub Main() procedure executes the XSLT transformation and writes the transformation output to a file named Output.xml in the project folder. The message "Done" appears in the console window when the transformation completes. Press any key to close the console window and return to the development environment.
6.In Solution Explorer, click Refresh button to view the Output.xml file in the project folder. When you open the Output.xml file, you will see that it contains the following XML:
<?xml version="1.0" encoding="utf-8"?>
<Data>
	<ValuesThatMatchPosition></ValuesThatMatchPosition>
	<Position3Value>3</Position3Value>
</Data>
					
The value elements in the source XML whose values match their position are not listed in the output as expected. The <Position3Element> element, however, has the correct value because the expression that is used in the style sheet to retrieve it uses the position function in a predicate (instead of directly as an XSLT function argument).

7.Close Output.xml, and then open the Repro.xsl style sheet.
8.Replace the <xsl:for-each> block that is used to generate the contents of the <ValuesThatMatchPosition> element with the following code to store the output of the position XPath function in an XSLT variable and supply the variable as the value parameter in the call to the key XSLT function:
<xsl:for-each select="value">
   <xsl:variable name="pos" select="position()"/>			
   <xsl:if test="key('Values',$pos)">
            <value><xsl:value-of select="."/></value>   		    
   </xsl:if>	   
</xsl:for-each>
					
9.Save the changes to the style sheet, and then reexecute the project. When you view the contents of Output.xml, you see the following XML:
<?xml version="1.0" encoding="utf-8"?>
<Data>
	<ValuesThatMatchPosition>
		<value>1</value>
		<value>2</value>
		<value>3</value>
		<value>5</value>
		<value>7</value>
	</ValuesThatMatchPosition>
	<Position3Value>3</Position3Value>
</Data>
					
The output now lists the value elements in the source XML whose values match their position.

Back to the top


APPLIES TO
•Microsoft .NET Framework 1.0

Back to the top

Keywords: 
kbbug kbpending KB324033

Back to the top

       

Community Feedback System

Very often, it takes hours to solve a problem. Very often, you've looked high and low, and have tried a lot of solutions. When you finally found it, chances are, it was because someone else helped you. Here's your chance to give back. Use our community feedback tool to let others know what worked for you and what didn't.

Please also understand that the community feedback system is not warranted to be correct, it's simply a system that we've built to let people try and help each other. If something in a feedback response doesn't make sense to you, or you're not comfortable making changes that the feedback talks about (like registry edits), please consult a professional.

Thank you for using kbAlertz.com Feedback System.

-- Scott Cate

Be the first to leave feedback, to help others about this knowledge base article.

(Optional) Name

(Optional) Public URL Or Email

Comments
No HTML -- Text Only Please