Pregunta

Me gustaría usar expresiones regulares para seleccionar elementos usando la función de coincidencia.Preferiría no utilizar una biblioteca externa (como saxon) para hacer esto.

¿Fue útil?

Solución

Hay algunas cosas en XSLT 2.0 que no son compatibles con las bibliotecas integradas (hubo una discusión en la lista de correo mono sobre esto pero ya no puedo encontrar la información).Pero la mayoría de la gente nunca se topa con casos extremos que no son compatibles.

Otra opción es consultar el código abierto. http://saxon.sourceforge.net/ que tiene un gran soporte para 2.0.

EDITAR (AB):La respuesta aceptada anteriormente puede resultar confusa.No hay ningún apoyo en absoluto y hay no hay planes en esa dirección para cualquiera de las funciones XPath 2.0 o XSLT 2.0 en .NET.

Otros consejos

Creo que la respuesta en esta discusión es engañosa.Creo que .NET 3.5 no es compatible con la mayoría de las funciones XSL/T 2.0 (si es que hay alguna).

Un ejemplo:

Una llamada a una función 2.0 genera el siguiente mensaje de error en .NET 3.5:

'current-dateTime()' es una función XSLT desconocida.

Creo que la respuesta anterior es incorrecta.No puedo encontrar ninguna evidencia de que Microsoft admita XSLT 2.0.XSLT! = XPath.

Para referencia futura, aquí hay una buena página sobre cómo extender xpath/xquery en .net:

http://www.csharpfriends.com/Articles/getArticle.aspx?articleID=64

No confío en que esto dure, así que lo copio aquí:


XSLT es un lenguaje de transformación para XML.Permite a los sistemas de servidor transformar el árbol XML de origen en una forma más adecuada para los clientes.XSLT utiliza patrones de nodos para compararlos con plantillas para realizar sus transformaciones.Aunque hace que las transformaciones complejas sean relativamente simples, hay algunas situaciones en las que es posible que tengamos que usar algunas clases personalizadas.

Algunas de las situaciones en las que podríamos necesitar extender XSLT son:

1) Llamar a la lógica empresarial personalizada
2) Realizar diferentes acciones dependiendo de los Permisos
3) Realizar formatos complejos para fechas, cadenas, etc.
4) ¡¡O incluso llamar a un servicio web!!

Pasos para extender XSLT

1) Cree el objeto personalizado para usar desde XSLT (en C#)

CustomDate custDate = new CustomDate() ;

2) Proporcionar una declaración de espacio de nombres personalizada para la clase personalizada dentro de la declaración de espacio de nombres XSLT (en un archivo XSLT)

<xsl:transform
        version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:myCustDate="urn:custDate">

3) Pase una instancia del objeto personalizado a XSLT, con el mismo espacio de nombres que en el último paso (en C#)

xslArgs.AddExtensionObject("urn:custDate", custDate) ;

4) Utilice el objeto desde XSLT (en un archivo XSLT)

<xsl:value-of select="myCustDate:GetDateDiff(./joiningdate)"/>

Código de muestra

Para nuestro ejemplo, supongamos que tenemos una hoja XSLT donde necesitamos manipular fechas.Necesitamos mostrar el número de días que el empleado ha estado en la empresa.Dado que XSLT no tiene funciones nativas de manipulación de fechas, usemos un objeto de extensión para nuestra tarea.

using System ;
using System.IO ;
using System.Xml ;
using System.Xml.Xsl ;
using System.Xml.XPath ;

public class XsltExtension{

    public static void Main(string[] args){

        if (args.Length == 2){

            Transform(args[0], args[1]) ;

        }else{

            PrintUsage() ;

        }
    }

    public static void Transform(string sXmlPath, string sXslPath){

        try{

            //load the Xml doc
            XPathDocument myXPathDoc = new XPathDocument(sXmlPath) ;

            XslTransform myXslTrans = new XslTransform() ;

            //load the Xsl 
            myXslTrans.Load(sXslPath) ;

            XsltArgumentList xslArgs = new XsltArgumentList() ;

            //create custom object
            CustomDate custDate = new CustomDate() ;

            //pass an instance of the custom object
            xslArgs.AddExtensionObject("urn:custDate", custDate) ;

            //create the output stream
            XmlTextWriter myWriter = new XmlTextWriter("extendXSLT.html", null) ;

            //pass the args,do the actual transform of Xml
            myXslTrans.Transform(myXPathDoc,xslArgs, myWriter) ;        

            myWriter.Close() ;

        }catch(Exception e){

            Console.WriteLine("Exception: {0}", e.ToString());
        }

    }

    public static void PrintUsage(){
        Console.WriteLine("Usage: XsltExtension.exe <xml path> >xsl path<") ;
    }

}

//our custom class
public class CustomDate{

    //function that gets called from XSLT
    public string GetDateDiff(string xslDate){

        DateTime dtDOB = DateTime.Parse(xslDate) ;

        DateTime dtNow = DateTime.Today ;

        TimeSpan tsAge = dtNow.Subtract(dtDOB) ;

        return tsAge.Days.ToString() ;
    }

}

Compile este código y utilice los member.xml y memberdisplay.xsl proporcionados para ejecutar esta aplicación de consola.Debería ver un archivo extendXSLT.html dentro de la misma carpeta.Abra este archivo y observe que se ha llamado a nuestra clase CustomDate para calcular la cantidad de días que el empleado ha estado en la empresa.

Resumen :
XSLT es un poderoso lenguaje de transformación para XML; sin embargo, el uso de objetos de extensión en .NET y C# debería garantizar que podamos lograr fácilmente lo que sería imposible o difícil solo con XSLT.

Miembros.xml:

 <root>
    <member>
        <name>Employee1</name>
        <joiningdate>01/01/1970</joiningdate>
        <role>CTO</role>
    </member>
    <member>
        <name>Employee2</name>
        <joiningdate>24/07/1978</joiningdate>
        <role>Web Developer</role>
    </member>
    <member>
        <name>Employee3</name>
        <joiningdate>15/12/1980</joiningdate>
        <role>Tester</role>
    </member>
</root>

Miembrodisplay.xsl:

<xsl:transform
        version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:myCustDate="urn:custDate">

<xsl:output method="html" omit-xml-declaration="yes" />     

    <xsl:template match="/">
        <html>
            <head>
                <style>
                    TABLE.tblMaster
                    {
                        border-style: solid; 
                        border-width: 1px 1px 1px 1px; 
                        border-style: solid; 
                        border-color:  #99CCCC; 
                        padding: 4px 6px; 
                        text-align: left; 
                        font-family:Tahoma,Arial;
                        font-size:9pt;

                    }
                    TD.tdHeader
                    {
                        FONT-WEIGHT: bolder;
                        FONT-FAMILY: Arial;
                        BACKGROUND-COLOR: lightgrey;
                        TEXT-ALIGN: center
                    }
                </style>
            </head>
            <body>
                <table width="50%" class="tblMaster">
                    <tr >
                        <td class="tdHeader">Employee</td>
                        <td class="tdHeader">Join date</td>
                        <td class="tdHeader">Days in company</td>
                        <td class="tdHeader">Role</td>
                    </tr>
                    <xsl:for-each select="/root/member">

                        <tr >
                            <td> <xsl:value-of select="./name"/> </td>

                            <td> <xsl:value-of select="./joiningdate"/> </td>

                            <td> <xsl:value-of select="myCustDate:GetDateDiff(./joiningdate)"/> </td>

                            <td> <xsl:value-of select="./role"/> </td>
                        </tr>   

                    </xsl:for-each>

                </table>
            </body>
        </html>
    </xsl:template>

</xsl:transform>        

Cuando se analiza la compatibilidad de .NET con XSLT 2.0, XPath 2.0 y XQuery 1.0, es importante distinguir entre los lenguajes mismos y el modelo de datos (XDM)..NET 3.5 Framework admite el modelo de datos, pero no los idiomas.Como me explicó recientemente Pawel Kadluczka de Microsoft mediante correspondencia por correo electrónico:

La oración "Las instancias del modelo de datos XQuery 1.0 y XPath 2.0" pueden ser confusos, pero creo que se refiere a W3C XQuery 1.0 y XPath 2.0 Data Model (XDM) Spec (http://www.w3.org/TR/xpath-datamodel) que dice:

[Definición:Cada instancia del modelo de datos es una secuencia.].

[Definición:Una secuencia es una colección ordenada de cero o más elementos.] Una secuencia no puede ser un miembro de una secuencia.Un solo elemento que aparece por sí solo se modela como una secuencia que contiene un elemento.Las secuencias se definen en 2.5 secuencias.

[Definición:Un elemento es un nodo o un valor atómico],

En el caso de XPath API - XPATHNodeiterator es la secuencia, mientras que XPATHITEM (XPATHNAVIGATOR) representa el elemento.

Sí, XPathNavigator 3.5 es compatible con XSLT 2.0.

http://msdn.microsoft.com/en-us/library/system.xml.xpath.xpathnavigator.aspx

"La clase XPathNavigator en el espacio de nombres System.Xml.XPath es una clase abstracta que define un modelo de cursor para navegar y editar elementos de información XML como instancias del modelo de datos XQuery 1.0 y XPath 2.0".

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top