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
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