C# How to perform a live xslt transformation on an in memory object?
I have a function that takes 2 parameters : 1 = XML file, 2 = XSLT file, then performs a transformation and returns the resulting HTML.
Here is the function:
/// <summary>
/// Will apply an XSLT style to any XML file and return the rendered HTML.
/// </summary>
/// <param name="xmlFileName">
/// The file name of the XML document.
/// </param>
/// <param name="xslFileName">
/// The file name of the XSL document.
/// </param>
/// <returns>
/// The rendered HTML.
/// </returns>
public string TransformXml(string xmlFileName, string xslFileName)
{
var xtr = new XmlTe开发者_运维技巧xtReader(xmlFileName)
{
WhitespaceHandling = WhitespaceHandling.None
};
var xd = new XmlDocument();
xd.Load(xtr);
var xslt = new System.Xml.Xsl.XslCompiledTransform();
xslt.Load(xslFileName);
var stm = new MemoryStream();
xslt.Transform(xd, null, stm);
stm.Position = 1;
var sr = new StreamReader(stm);
xtr.Close();
return sr.ReadToEnd();
}
I want to change the function not to accept a file for the XML, but instead just an object. The object is exactly compatible with the xslt, if it was serialized to file. But I don't want to have to serialize it to a file first.
So to recap : keep the xslt coming from a file, but the xml input should an object I pass and would like to generate the xml from without any file system interaction.
You can serialize the object to a string, load the string into a XmlDocument
, and perform the transformation :
public string TransformXml(object data, string xslFileName)
{
XmlSerializer xs = new XmlSerializer(data.GetType());
string xmlString;
using (StringWriter swr = new StringWriter())
{
xs.Serialize(swr, data);
xmlString = swr.ToString();
}
var xd = new XmlDocument();
xd.LoadXml(xmlString);
var xslt = new System.Xml.Xsl.XslCompiledTransform();
xslt.Load(xslFileName);
var stm = new MemoryStream();
xslt.Transform(xd, null, stm);
stm.Position = 0;
var sr = new StreamReader(stm);
return sr.ReadToEnd();
}
Here's a function that will turn an object into a XDocument (you can change it for XmlDocument if you aren't using XDocument yet). Of course this will throw exceptions if the object is not serializeable.
public static XDocument ConvertToXml<T>(this T o)
{
StringBuilder builder = new StringBuilder();
StringWriter writer = new StringWriter(builder);
XmlSerializer serializer = new XmlSerializer(typeof(T));
serializer.Serialize(writer,o);
StringReader reader = new StringReader(builder.ToString());
return XDocument.Load(reader);
}
and here's the one for XmlDocument
public static XmlDocument ConvertToXml<T>(this T o)
{
StringBuilder builder = new StringBuilder();
StringWriter writer = new StringWriter(builder);
XmlSerializer serializer = new XmlSerializer(typeof(T));
serializer.Serialize(writer,o);
StringReader reader = new StringReader(builder.ToString());
XmlDocument doc = new XmlDocument();
doc.Load(reader);
return doc;
}
Not tested, but you can use the XPathDocument to take a Stream, and since XPathDocument implements IXPathNavigable, it can be used for transformations:
public string TransformXml(Stream xmlFile, string xslFileName)
{
var doc = new XPathDocument(xmlFile);
var xslt = new System.Xml.Xsl.XslCompiledTransform();
xslt.Load(xslFileName);
var stm = new MemoryStream();
xslt.Transform(doc, null, stm);
stm.Position = 1;
var sr = new StreamReader(stm);
return sr.ReadToEnd();
}
Take a look at this article which describes creating an XPathNavigator
that can navigate the properties of an object graph, which is a pretty powerful combination of XPath and XSLT.
精彩评论