Tuesday, March 1, 2011

Simplest way to transform XML to HTML with XSLT in C#?

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!

From stackoverflow
  • 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).

    Dathan : +1: it doesn't get any simpler than this.
    Shaul : Marc, you are a prince among men. :)
  • 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;
        }
    
    Marc Gravell : You'd have to worry about thread safety / synchronization around the dictionary, but something along those lines, yes.
    Dathan : 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.

0 comments:

Post a Comment