Hi Group,
I think I have found a problem with the <xsl:element> when being
transformed by the .NET xmlTransform class. When using XmlSpy for
development and debugging, the <xsl:number> subsitutes the position of the
node correctly as I expected. This is fine with MSXML 3.0 & MSXML 4.0 plus
the XmlSpy internal engine.
I have been able to reproduce using a simpler Xml and Xsl to demonstrate;
XML
===
<?xml version="1.0" encoding="UTF-8"?>
<html>
<head><title>Tester</title></head>
<body>
<h4 class="no">Table 1</h4>
<table><tbody><tr><td>Some Data</td></tr></tbody></table>
<h4 class="yes">Table 2</h4>
<table><tbody><tr><td>Some Data</td></tr><tr><td>Some Data
2</td></tr><tr><td>Some Data 3</td></tr></tbody>
</table>
<h4 class="yes">Table 3</h4>
<table><tbody><tr><td>Some Data</td></tr><tr><td>Some Data
2</td></tr><tr><td>Some Data 3</td></tr></tbody></table>
<h4 class="yes">Table 4</h4>
<table><tbody><tr><td>Some Data</td></tr><tr><td>Some Data
2</td></tr></tbody></table>
</body>
</html>
My XSL needs to return all rows that are in a table that has @class = 'yes'
and set an id attribute to the absolute position in the document - in
relation to all tables with @class = 'yes'.
XSL that achieves this
===============
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/">
<xsl:element name="TableMatch">
<xsl:apply-templates select="//h4[@class='yes']" />
</xsl:element>
</xsl:template>
<xsl:template match="h4">
<xsl:element name="Table">
<xsl:for-each select="following-sibling::table[1]/tbody/tr">
<xsl:element name="row">
<xsl:attribute name="id">
<xsl:number level="any" from="//h4[@class='yes'][1]" />
</xsl:attribute>
<xsl:value-of select="td" />
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
This produces Output
==============
<?xml version="1.0" encoding="UTF-16"?>
<TableMatch>
<Table>
<row id="1">Some Data</row>
<row id="2">Some Data 2</row>
<row id="3">Some Data 3</row>
</Table>
<Table>
<row id="4">Some Data</row>
<row id="5">Some Data 2</row>
<row id="6">Some Data 3</row>
</Table>
<Table>
<row id="7">Some Data</row>
<row id="8">Some Data 2</row>
</Table>
</TableMatch>
Which is great! Now when I try the transformation using the following code
(C#);
public static void Main()
{
doc = new XPathDocument(inputFile); // Create New
XPath Document to open File
XPathNavigator navi = doc.CreateNavigator(); // Create
XPathNavigator to navigate through document
writer = new XmlTextWriter("xlsnumberOutput.xml" , Encoding.UTF8); //
Create new xmlTextWriter
// Now need to transform into Xml format
XslTransform transform = new XslTransform();
transform.Transform(doc, null, writer, new XmlUrlResolver());
// Kill Writer
writer.Flush();
writer.Close();
}
The <xsl:number> element is returning a blank string i.e. nothing and the
output is as follows;
<TableMatch>
<Table>
<row id="">Some Data</row>
<row id="">Some Data 2</row>
<row id="">Some Data 3</row>
</Table>
<Table>
<row id="">Some Data</row>
<row id="">Some Data 2</row>
<row id="">Some Data 3</row>
</Table>
<Table>
<row id="">Some Data</row>
<row id="">Some Data 2</row>
</Table>
</TableMatch>
@id is blank! The reason I want the @id in this way is because I want to
generate a unique identity across *all* matching rows. The .NET transform
has some problem achieving this.
Can anyone advise what the problem is here or some way of working around
this?
TIA (if you got this far :p)
b0yce