XslTransform class is deprecated after .NET conversion - c#

I had XslTransform in an old program, and after converting the code the the .NET F 3.5, the compiler said that XslTransform is deprecated and replaced by XslCompiledTransform.
This is the old code :
XslTransform xslt = new XslTransform();
xslt.Load(xslTemplate);
xslt.Transform(xPathNav, null, fileStream, null);
I've changed the code to look like this :
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(xslTemplate);
xslt.Transform(xPathNav, fileStream);
And now I get :
cannot convert from
'System.IO.FileStream' to
'System.Xml.XmlWriter'
I tried to correct that by adding doing this :
XPathDocument doc = new XPathDocument(fileStream);
XmlWriter writer = XmlWriter.Create(Console.Out, xslt.OutputSettings);
xslt.Transform(doc, writer);
I don't get errors anymore, but I the code is not doing XML transformation.
Any ideas ?
Thanks.

I think
XslTransform xslt = new XslTransform();
xslt.Load(xslTemplate);
xslt.Transform(xPathNav, null, fileStream, null);
can be written as follows with XslCompiledTransform
XslTransform xslt = new XslCompiledTransform();
xslt.Load(xslTemplate);
xslt.Transform(xPathNav, null, fileStream);

MSDN actually has a full article on Migrating From XslTransform to XslCompiledTransform

In the first couple of code snippets, you seem to be using fileStream for output and xPathNav for input.
But in the last snippet, you're using fileStream (via doc) for input.
Did you really change fileStream to be your input document, or is this a mistake?

Related

Apply XSLT on an XmlDocument and get the updated XmlDocument

I've to make an upgrade mechanism which will update an XML documents(To another xml document).
The signature of the method that I've to respect is :
public XmlDocument Update(XmlDocument sourceDocument){...}
What would be the most efficient way to apply an XSLT file on this?
I was expecting to be able to use the XslTransform class, but it only accept stream and XmlWriter as parameter for the output.
So I know that I could do something like:
public XmlDocument Update(XmlDocument sourceDocument){
XslTransform myXslTransform = new XslTransform();
myXslTransform.Load("myXsl.xsl");
MemoryStream ms = new MemoryStream();
myXslTransform.Transform(sourceDocument, null, ms);
XmlDocument output = new XmlDocument();
output.Load(ms);
return output;
}
But I find this not very efficient(knowing that my XSLT will be to rename some nodes, add a node in-between, add a child). Is there a way to do better?
My "only" constraints are: Input/Output: XmlDocument, External XSLT to load.
If you want to use a System.Xml.XmlDocument with the current XSLT 1.0 implementation (XslCompiledTransform) that Microsoft offers then you can use
XmlDocument resultDocument = new XmlDocument();
using (XmlWriter xw = resultDocument.CreateNavigator().AppendChild()) {
XslCompiledTransform proc = new XslCompiledTransform();
proc.Load("myXsl.xsl");
proc.Transform(sourceDocument, null, xw);
xw.Close();
}
return resultDocument;

XslTransform to XslCompiledTransform

Currently I have this code which works fine but I want to migrate to XslCompiledTransform. When this code was written the evidence was required or it would not work. Does anybody know if this is still required in the XslCompiledTransform.
XslTransform transformer = new XslTransform();
transformer.Load( navigator, new XmlUrlResolver(), this.GetType().Assembly.Evidence);
Here is my suggested code to change to.
XslCompiledTransform transform = new XslCompiledTransform();
transform.Load( navigator,new XsltSettings(), new XmlUrlResolver() );
If you use new XsltSettings() then you are using default settings with both script and the document function being disabled. That would be equivalent to using
XslTransform transformer = new XslTransform();
transformer.Load( navigator, new XmlUrlResolver(), null);

Output Param from XSLT

I have been familiar with passing Input Param to XSLT CompiledTransformation class, so that parser takes care of XSL file making use of Param in processing instruction provided in XSL file.
Is there a way where we can get output param (say a value of node or something else) from XSLT to host language like C#??
XslCompiledTransform xslTransform = new XslCompiledTransform();
string strXmlOutput = string.Empty;
StringWriter swXmlOutput = null;
MemoryStream objMemoryStream = null;
XPathDocument xpathXmlOrig = new XPathDocument(string_xmlInput);
swXmlOutput = new StringWriter();
objMemoryStream = new MemoryStream();
xslArg.AddParam("TESTING", "", SomeVar);
XsltSettings xslsettings = new XsltSettings(false, true);
xslTransform.Load(string_xslInput, xslsettings, new XmlUrlResolver());
xslTransform.Transform(xpathXmlOrig, xslArg, objMemoryStream);
This code indeed outputs transformed XML, but my question is can we take just one value as output param from XSL Tranformation (XSLT file)??
Something like this:
xslArg.OutputParam("testing"); //Something like this?
........
........
xslTransform.Transform(xpathXmlOrig, xslArg, objMemoryStream);
string outputparam = xslArg.GetParam("testing"); //ideal way of getting param after traformation!
Does XSLT provides scope for something like this?
In C#, your best bet is to put <xsl:message> instructions in your XSLT code, and hook into the XsltMessageEncountered event on the XsltArgumentList class.
You can test it's giving you the correct output without hooking the event, by watching the output of the app- in the absence of an event handler, messages are piped to standard output.

How to create a XML with a Specific Encoding using XSLT and XMLWRITER

I am trying to apply a XSL style sheet on a source xml and write the output to a target xml file. The xsl removes the xml comments present inside the source xml.
The target xml file has UTF-16 encoding in the header.
But still i want the output xml to be utf-8 encoding. The code i used is
XmlWriterSettings xwrSettings = new XmlWriterSettings();
**xwrSettings.Encoding = Encoding.UTF8;**
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load("sample.xsl");
StringBuilder sb = new StringBuilder();
XmlReader xReader = XmlReader.Create("Source.xml");
XmlWriter xWriter = XmlWriter.Create(sb, xwrSettings);
xslt.Transform(xReader, xWriter);
File.WriteAllText("Target.xml",sb.ToString());
I tried to set the xml writer setting to be of UTF-8 but it is not working.
Since you are writing to file, why not just use:
using (XmlReader xReader = XmlReader.Create("Source.xml"))
using (XmlWriter xWriter = XmlWriter.Create("Target.xml", xwrSettings)) {
xslt.Transform(xReader, xWriter);
}
// your file is now written

Apply XSLT on in-memory XML and returning in-memory XML

I am looking for a static function in the .NET framework which takes an XML snippet and an XSLT file, applies the transformation in memory, and returns the transformed XML.
I would like to do this:
string rawXml = invoiceTemplateDoc.MainDocumentPart.Document.InnerXml;
rawXml = DoXsltTransformation(rawXml, #"c:\prepare-invoice.xslt"));
// ... do more manipulations on the rawXml
Alternatively, instead of taking and returning strings, it could be taking and returning XmlNodes.
Is there such a function?
You can use the StringReader and StringWriter classes :
string input = "<?xml version=\"1.0\"?> ...";
string output;
using (StringReader sReader = new StringReader(input))
using (XmlReader xReader = XmlReader.Create(sReader))
using (StringWriter sWriter = new StringWriter())
using (XmlWriter xWriter = XmlWriter.Create(sWriter))
{
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load("transform.xsl");
xslt.Transform(xReader, xWriter);
output = sWriter.ToString();
}
A little know feature is that you can in fact transform data directly into a XmlDocument DOM or into a LINQ-to-XML XElement or XDocument (via the CreateWriter() method) without having to pass through a text form by getting an XmlWriter instance to feed them with data.
Assuming that your XML input is IXPathNavigable and that you have loaded a XslCompiledTransform instance, you can do the following:
XmlDocument target = new XmlDocument(input.CreateNavigator().NameTable);
using (XmlWriter writer = target.CreateNavigator().AppendChild()) {
transform.Transform(input, writer);
}
You then have the transformed document in the taget document. Note that there are other overloads on the transform to allow you to pass XSLT arguments and extensions into the stylesheet.
If you want you can write your own static helper or extension method to perform the transform as you need it. However, it may be a good idea to cache the transform since loading and compiling it is not free.
Have you noticed that there is the XsltCompiledTransform class?

Categories