PRB: The XSLT current() method may return incorrect data when try to count the number of consecutive elements with the same key value (841763)
The information in this article applies to:
- Microsoft .NET Framework 1.1
- Microsoft XML 3.0 SP3
- Microsoft XML 4.0 SP1
SYMPTOMSYou use the Extensible Stylesheet Language for Transformations (XSLT) current() method when transforming XML data. When try to count the number of consecutive elements
with the same key value, you may receive incorrect
results.RESOLUTIONUse the workaround that is suggested in this article, or
upgrade to MSXML 4.0 Service Pack 2 (SP2).STATUSMicrosoft
has confirmed that this is a problem in the Microsoft products that are listed
in the "Applies to" section. This problem was corrected in MSXML 4.0 Service Pack 2.
WORKAROUNDReplace the code in step 2 of the "Steps to reproduce the
behavior" section. To do this, paste the following code in Notepad to create the XSL style sheet, and then save
the file as prod.xsl. <?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:hashtable="urn:hashtable">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<msxsl:script language="C#" implements-prefix="hashtable">
System.Collections.Hashtable table = new System.Collections.Hashtable();
public string Add(string key) {
if (table.ContainsKey(key)) {
table[key] = (int)table[key] + 1;
}
else {
table.Add(key, 1);
}
return string.Empty;
}
public int Get(string key) {
if (table.ContainsKey(key)) {
return (int)table[key];
}
else {
return 0;
}
}
</msxsl:script>
<xsl:strip-space elements="*" />
<xsl:variable name="dummy">
<xsl:for-each select="//Product">
<xsl:value-of select="hashtable:Add(generate-id(following-sibling::Product[@name != current()/@name][1]))"/>
</xsl:for-each>
</xsl:variable>
<xsl:template match="Products">
<Products>
<xsl:apply-templates select="Product[1]"/>
</Products>
</xsl:template>
<xsl:template match="Product">
<Product name="{@name}" count="{hashtable:Get(generate-id(following-sibling::Product[@name != current()/@name][1]))}"/>
<xsl:apply-templates select="following-sibling::Product[@name !=current()/@name][1]"/>
</xsl:template>
</xsl:stylesheet>
When you modify the XSL style sheet, make sure that you do the following:
- Locate the following code.
<xsl:key name="key-name" match="pattern" use="string-expression" /> Replace it with the following code. <xsl:for-each select="//pattern">
<xsl:value-of select="key:Add('key-name', string-expression, .)"/>
</xsl:for-each> - Locate the following code.
key(key-name, string-expression) Replace it with the following code.key:Get(key-name, string-expression)
Modification Type: | Major | Last Reviewed: | 1/11/2005 |
---|
Keywords: | kbprb KB841763 kbAudDeveloper |
---|
|