handy XSLT Extensions

2008-04-07 @ 13:21#

adding custom functions to XSLT transforms can be a real advantage. i do enough in XSLT that it helps to have some common functions at the ready. declaring and using them in an XSLT document is simple. adding them to the transform stream in C# is pretty simple, too.

here's how the XSLT document looks when declaring and using imported custom functions from the runtime:

// declare custom functions in the XSL document
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:exyus="urn:exyus-functions">

// use the custom functions in your XSLT document
<xsl:value-of select="exyus:MD5(.)"/>
<xsl:value-of select="exyus:MD5(.,'true')"/>
<xsl:value-of select="exyus:MD5BinHex(.)"/>
<xsl:value-of select="exyus:SHA1(.)"/>
<xsl:value-of select="exyus:Base64Encode(.)"/>
<xsl:value-of select="exyus:UID()"/>
<xsl:value-of select="exyus:GUID()"/>
<xsl:value-of select="exyus:HttpHeader('accept')"/>
<xsl:value-of select="exyus:ServerVar('http_accept')"/>
<xsl:value-of select="exyus:UrlEncode(exyus:ServerVar('url'))"/>

and here's the code that passes the function class into the transform stream in C#:

// add custom extensions to XSLT
private string TransformData()
{
    string rtn = string.Empty;
    XmlDocument xmldoc = new XmlDocument();
    XmlDocument xsldoc = new XmlDocument();
    XsltArgumentList args = new XsltArgumentList();
    XsltFunctions functions = new XsltFunctions();
    
    args.AddExtensionObject("urn:exyus-functions", functions);
    xmldoc.LoadXml("data.xml);
    xsldoc.Load("data.xsl");

    XPathNavigator xdNav = xmldoc.CreateNavigator();
    XslTransform tr = new XslTransform();
    tr.Load(xsldoc);
    StringWriter sw = new StringWriter();
    tr.Transform(xdNav,args, sw);
    rtn = sw.ToString();

    return rtn;
}

finally, here's a sample class of common functions that i keep ready to pass into the transform stream:

// handy functions to import into XSLT Transforms
class XsltFunctions
{
    public XsltFunctions(){}

    public string MD5(string data)
    {
        return MD5(data, false);
    }
    public string MD5(string data, string removeTail)
    {
        return MD5(data,(removeTail.ToLower()=="true"?true:false));
    }
    public string MD5(string data, bool removeTail)
    {
        string rtn = Convert.ToBase64String(new System.Security.Cryptography.MD5CryptoServiceProvider().ComputeHash(System.Text.Encoding.Default.GetBytes(data)));
        if (removeTail)
            return rtn.Replace("=", "");
        else
            return rtn;
    }

    public string MD5BinHex(string val)
    {
        Encoding encoding = new ASCIIEncoding();
        byte[] bs = new System.Security.Cryptography.MD5CryptoServiceProvider().ComputeHash(encoding.GetBytes(val));
        string hash = "";

        for (int i = 0; i < 16; i++)
            hash = String.Concat(hash, String.Format("{0:x02}", bs[i]));

        return hash;
    }

    public string SHA1(string data)
    {
        string rtn = string.Empty;
        System.Security.Cryptography.SHA1CryptoServiceProvider md = new System.Security.Cryptography.SHA1CryptoServiceProvider();

        byte[] digest = md.ComputeHash(Encoding.Default.GetBytes(data));
        foreach (byte i in digest)
        {
            rtn += i.ToString("x2");
        }
        return rtn;

    }

    public string Base64Encode(string str)
    {
        byte[] encbuff = System.Text.Encoding.UTF8.GetBytes(str);
        return Convert.ToBase64String(encbuff);
    }
    public string Base64Decode(string str)
    {
        byte[] decbuff = Convert.FromBase64String(str);
        return System.Text.Encoding.UTF8.GetString(decbuff);
    }

    public string UID()
    {
        return string.Format("x{0:x}", DateTime.UtcNow.Ticks);
    }

    public string GUID()
    {
        return System.Guid.NewGuid().ToString();
    }

    public string HttpHeader(string name)
    {
        if (HttpContext.Current.Request.Headers[name] != null)
            return HttpContext.Current.Request.Headers[name];
        else
            return string.Empty;
    }

    public string ServerVar(string key)
    {
        return HttpContext.Current.Request.ServerVariables[key];
    }

    public string UrlEncode(string data)
    {
        return HttpContext.Current.Server.UrlEncode(data);
    }
}

code