6

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?

3 Answers 3

7

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();
}
Sign up to request clarification or add additional context in comments.

3 Comments

Since there obviously is an XmlDocument already (he uses ….Document.InnerXml), using StringReader seems superfluous.
...and pretty inefficient because the XML is serialized to a string and then parsed again.
it's not, actually. It looks like it, but it is the OpenXML SDK for reading docx files which has an API very similar to the XmlDocument API, and the API's are not compatible. So I think the downvote is not justified by that.
5

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.

Comments

1

Have you noticed that there is the XsltCompiledTransform class?

2 Comments

Yes. But that class has only filenames, stream, readers or writers as input arguments for its Transform method. It involves a lot of messing around with memorystreams to accomplish a simple transformation on an in-memory XML snippet.
XmlDocument implements IXPathNavigable, so you can pass it as input directly. For output, see stackoverflow.com/questions/1346995/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.