Buscar este blog

jueves, 31 de enero de 2013

Usando c# en xslt

En .Net el soporte de xslt se limita a la version 1 y no parece que esto vaya a cambiar pronto asi que estamos muy limitados en cuanto a lo que se puede hacer: hay pocas funciones y no se pueden declarar funciones nuevas.
Afortunadamente Microsoft incluyo soporte para crear funciones nuevas funciones en cualquier lenguaje de .Net esto es a través del elemento <msxsl:script />
En el ejemplo creamos la función Trim que no tiene equivalente en xslt (aunque normalize-space se parece)
Hay que recordar que esto solo se soporta en m$, si vas a usar tu xslt con otras aplicaciones no va a funcionar.
Para activarlo con la clase  XslCompiledTransform se debe cargar el xslt con un objecto XsltSettings con la propiedad EnableScript en true:
XsltSettings xsltSettings = new XsltSettings();
xsltSettings.EnableScript = true;
XslCompiledTransform transform = new XslCompiledTransform(false);
transform.Load(styleSheet, xsltSettings, new XmlUrlResolver());



<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt"
    exclude-result-prefixes="msxsl"
    xmlns:user="urn:my-scripts"
>
    <msxsl:script language="C#" implements-prefix="user">
        <![CDATA[
            public string Trim(string input) {
                return input.Trim();
            }
        ]]>
    </msxsl:script>
    <xsl:output method="xml" indent="yes"/>
 
    <xsl:template match="/">
        <NewRoot>
            <xsl:for-each select="OldValues/OldValue">
                <NewValue>
                    <Id>
                        <xsl:value-of select="user:Trim(Id)"/>
                    </Id>
                </NewValue>
            </xsl:for-each>
        </NewRoot>
    </xsl:template>
</xsl:stylesheet>