Reputation: 289
I'm working on a project which requires me to load an xml document into xslt and transform it to display in an html table. The problem is that because I am using LINQ to create the XML, all of the element tags are XElement tags, so the "xsl:value-of select" property wont read an XElement. I'm wondering if there is a way to convert XElement to XmlElement or simply have XSLT read XElements instead of XMLElements?
Here is the code where I load data into the xml file via LINQ:
List<Prod> Products = utils.getProducts();
XElement xml = new XElement("Products", Products.Select(x => new XElement("Product",
new XElement("ProductID", x.ProductID),
new XElement("ProductName", x.ProductName),
new XElement("SupplierID", x.SupplierID),
new XElement("CategoryID", x.CategoryID),
new XElement("QuantityPerUnit", x.QuantityPerUnit),
new XElement("UnitPrice", x.UnitPrice),
new XElement("UnitInStock", x.UnitInStock),
new XElement("UnitsOnOrder", x.UnitsOnOrder),
new XElement("ReorderLevel", x.ReorderLevel))));
xml.Save("C:/Users/Aaron/Documents/Visual Studio 2012/WebSites/INFO451Final/Part_B/Prod.xml");
Here is the Code for my XSLT:
<xsl:template match="/">
<html>
<body>
<h2>Products</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>ProductID</th>
<th>ProductName</th>
<th>SupplierID</th>
<th>CategoryID</th>
<th>QuantityPerUnit</th>
<th>UnitPrice</th>
<th>UnitInStock</th>
<th>UnitsOnOrder</th>
<th>ReorderLevel</th>
</tr>
<xsl:for-each select="Product">
<tr>
<td>
<xsl:value-of select="ProductID"/>
</td>
<td>
<xsl:value-of select="ProductName"/>
</td>
<td>
<xsl:value-of select="SupplierID"/>
</td>
<td>
<xsl:value-of select="CategoryID"/>
</td>
<td>
<xsl:value-of select="QuantityPerUnit"/>
</td>
<td>
<xsl:value-of select="UnitPrice"/>
</td>
<td>
<xsl:value-of select="UnitInStock"/>
</td>
<td>
<xsl:value-of select="UnitsOnOrder"/>
</td>
<td>
<xsl:value-of select="ReorderLevel"/>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
So, right now all that loads are the headers since the "xsl:for-each" also doesn't work.
Any help would be greatly appreciated.
Upvotes: 2
Views: 3049
Reputation: 243459
Just use: your.xDocument.CreateNavigator()
and pass the result as a parameter to the Transform()
method of XslCompiledTransform
.
Here is an example exactly how to do this:
string xslMarkup = @"<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
<xsl:template match='/Parent'>
<Root>
<C1><xsl:value-of select='Child1'/></C1>
<C2><xsl:value-of select='Child2'/></C2>
</Root>
</xsl:template>
</xsl:stylesheet>";
XDocument xmlTree = new XDocument(
new XElement("Parent",
new XElement("Child1", "Child1 data"),
new XElement("Child2", "Child2 data")
)
);
XDocument newTree = new XDocument();
using (XmlWriter writer = newTree.CreateWriter()) {
// Load the style sheet.
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(XmlReader.Create(new StringReader(xslMarkup)));
// Execute the transform and output the results to a writer.
xslt.Transform(xmlTree.CreateNavigator(), writer);
}
Console.WriteLine(newTree);
This example produces the following output:
<Root>
<C1>Child1 data</C1>
<C2>Child2 data</C2>
</Root>
For more information see this MSDN document: Extensions.CreateNavigator Method (XNode)
Upvotes: 1