tags:

views:

176

answers:

2

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!

+7  A: 

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).

Marc Gravell
+1: it doesn't get any simpler than this.
Dathan
Marc, you are a prince among men. :)
Shaul
+1  A: 

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;
    }
Dathan
You'd have to worry about thread safety / synchronization around the dictionary, but something along those lines, yes.
Marc Gravell
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.
Dathan