23

XSLT newbie question: Please fill in the blank in the C# code fragment below:

public static string TransformXMLToHTML(string inputXml, string xsltString) {
  // insert code here to apply the transform specified by xsltString to inputXml 
  // and return the resultant HTML string.
  // You may assume that the xslt output type is HTML.
}

Thanks!

0

2 Answers 2

47

How about:

public static string TransformXMLToHTML(string inputXml, string xsltString)
{
    XslCompiledTransform transform = new XslCompiledTransform();
    using(XmlReader reader = XmlReader.Create(new StringReader(xsltString))) {
        transform.Load(reader);
    }
    StringWriter results = new StringWriter();
    using(XmlReader reader = XmlReader.Create(new StringReader(inputXml))) {
        transform.Transform(reader, null, results);
    }
    return results.ToString();
}

Note that ideally you would cache and re-use the XslCompiledTransform - or perhaps use XslTransform instead (it is marked as deprecated, though).

Sign up to request clarification or add additional context in comments.

3 Comments

Marc, you are a prince among men. :)
Very neat and simple.
well it can get simpler than this. All those XML readers can be replaced with actual location of the files like: XslCompiledTransform transform = new XslCompiledTransform("file://"+xsltString); Also transform has a version that you can pass the location of the file using that "file://" + inputXml trick ;)
4

Just for fun, a slightly less elegant version that implements the caching suggested by Marc:

    public static string TransformXMLToHTML(string inputXml, string xsltString)
    {
        XslCompiledTransform transform = GetAndCacheTransform(xsltString);
        StringWriter results = new StringWriter();
        using (XmlReader reader = XmlReader.Create(new StringReader(inputXml)))
        {
            transform.Transform(reader, null, results);
        }
        return results.ToString();
    }

    private static Dictionary<String, XslCompiledTransform> cachedTransforms = new Dictionary<string, XslCompiledTransform>();
    private static XslCompiledTransform GetAndCacheTransform(String xslt)
    {
        XslCompiledTransform transform;
        if (!cachedTransforms.TryGetValue(xslt, out transform))
        {
            transform = new XslCompiledTransform();
            using (XmlReader reader = XmlReader.Create(new StringReader(xslt)))
            {
                transform.Load(reader);
            }
            cachedTransforms.Add(xslt, transform);
        }
        return transform;
    }

2 Comments

You'd have to worry about thread safety / synchronization around the dictionary, but something along those lines, yes.
And it occurs to me that it might be worthwhile to hash the xsltString and use that hash as a key instead. Some transforms can get pretty big - no reason to incur the extra memory penalty storing it in compiled form in the XslCompiledTransform and again as the key.

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.