tags:

views:

455

answers:

2

Currently I have some legacy ASP.NET 2.0 code that uses the ASP Xml web control like this:

<asp:Xml ID="XmlResult" runat="server" />

This is used to perform an XSLT transformation in c# code-behind like this:

XslTransform xslt = new XslTransform();
xslt.Load(Server.MapPath("~/xslt/MyXsltFile.xslt"));
XmlResult.Transform = xslt;
XmlResult.TransformArgumentList = xslArgs; // these are created elsewhere

XmlResult.XPathNavigator = xd.CreateNavigator(); // xd is an XmlDocument()

The problem is that the ASP XML control expects an XltTransform object and this is deprecated (marked as obsolete) as from NET 2.0:

"The XslTransform class is obsolete in the Microsoft .NET Framework version 2.0. The XslCompiledTransform class is the new XSLT processor."

However, I can't seem to figure out how to replace this to use an XslCompiledTransform object. Obviously you can just give XmlResult.Transform property an XslCompiledTransoform object as this won't work. So presumably will have to replace the ASP Xml control with something else? A Literal? A Placeholder? But then what...? I just can't seem to work out the best way of doing this.

Any help would be appreciated! Thanks.

+2  A: 

This is a helper function from my library on CodePlex that might help you:

public static string GetXslString(IXPathNavigable xslSet, XsltArgumentList xslArgs, IXPathNavigable navigableSet)
{
        XslCompiledTransform xslt = new XslCompiledTransform(false);
        xslt.Load(xslSet);

        string ret = null;

        using(MemoryStream ms = new MemoryStream())
        {
            xslt.Transform(navigableSet, xslArgs, ms);
            ms.Position = 0;

            ret = XmlUtility.GetText(ms);
        }
        return ret;
}
rasx
Thanks, I will try that on Monday and see if it helps...
Dan Diplo
A: 

I finally figured out this and thought I'd provide the answer in case it proves useful to others. Below is a small helper class that uses XsltCompiledTransform and also can cache the results. It was written specifically for caching Umbraco macros, but can be used in any situation, I believe.

public static class XsltHelper
{
    /// <summary>
    /// Returns a compiled XSLT transform object for an XSLT file and caches it
    /// </summary>
    /// <param name="XsltFile">The relative path to the XSLT file</param>
    /// <returns>An XslCompiledTransform object for the XSLT file</returns>
    public static XslCompiledTransform GetXslt(string XsltFile)
    {
        string cacheKey = "macroXslt_" + XsltFile;

        if (System.Web.HttpRuntime.Cache[cacheKey] != null)
        {
            return (XslCompiledTransform)System.Web.HttpRuntime.Cache[cacheKey];
        }
        else
        {
            return GetXSLT(XsltFile, cacheKey);
        }
    }

    private static XslCompiledTransform GetXSLT(string XsltFile, string cacheKey)
    {
        XslCompiledTransform macroXSLT = new XslCompiledTransform();

        using (XmlTextReader xslReader = new XmlTextReader(System.Web.HttpContext.Current.Server.MapPath(XsltFile)))
        {
            try
            {
                xslReader.EntityHandling = EntityHandling.ExpandCharEntities;
                XmlUrlResolver xslResolver = new XmlUrlResolver();
                xslResolver.Credentials = CredentialCache.DefaultCredentials;

                XsltSettings settings = new XsltSettings();
                settings.EnableDocumentFunction = true;
                settings.EnableScript = true;
                macroXSLT.Load(xslReader, settings, xslResolver);

                System.Web.HttpRuntime.Cache.Insert(cacheKey, macroXSLT,
                    new System.Web.Caching.CacheDependency(System.Web.HttpContext.Current.Server.MapPath(XsltFile)));
            }
            catch
            {
                throw;
            }
        }

        return macroXSLT;
    }

}

Dan Diplo