Question

J'aimerais utiliser des expressions régulières pour sélectionner des éléments à l'aide de la fonction de correspondance. Je préférerais ne pas utiliser une bibliothèque externe (telle que saxon) à cette fin.

Était-ce utile?

La solution

Certaines choses dans XSLT 2.0 ne sont pas prises en charge dans les bibliothèques intégrées (il y a eu une discussion à ce sujet sur la liste de diffusion mono, mais je ne trouve plus les informations). Mais la plupart des gens ne se heurtent jamais à des problèmes non supportés.

Une autre option consiste à consulter le code source libre http://saxon.sourceforge.net/ . supporte très bien la version 2.0.

EDIT (AB): la réponse acceptée ci-dessus peut prêter à confusion. Il n'y a aucun support et il y a aucun plan dans cette direction pour une des fonctions XPath 2.0 ou XSLT 2.0 dans .NET.

Autres conseils

Je pense que la réponse à cette discussion est trompeuse. Je pense que .NET 3.5 ne supporte pas la plupart des fonctions XSL / T 2.0 (le cas échéant).

Un exemple :

Un appel à une fonction 2.0 donne le message d'erreur suivant sous .NET 3.5:

'current-dateTime ()' est une fonction XSLT inconnue.

Je pense que la réponse ci-dessus est fausse. Je ne trouve aucune preuve que Microsoft supporte XSLT 2.0. XSLT! = XPath.

Pour référence future, voici une belle page sur l'extension de xpath / xquery en .net:

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

Je ne crois pas que cela durera longtemps, je le copie donc ici:

XSLT est un langage de transformation pour XML. Il permet aux systèmes de serveur de transformer l’arborescence XML source en un format plus approprié pour les clients. XSLT utilise des modèles de noeud pour établir une correspondance avec des modèles afin d'effectuer ses transformations. Bien que les transformations complexes soient relativement simples, il existe des situations dans lesquelles nous pourrions être amenés à utiliser certaines classes personnalisées.

Certaines des situations dans lesquelles nous pourrions avoir besoin d'étendre XSLT sont les suivantes:

1) Appelez la logique métier personnalisée
2) Effectuer différentes actions en fonction des autorisations
3) Effectuez un formatage complexe pour les dates, les chaînes, etc.
4) Ou même appeler un webservice !!

Étapes pour étendre XSLT

1) Créez l'objet personnalisé à utiliser à partir de XSLT (en C #)

CustomDate custDate = new CustomDate() ;

2) Fournissez une déclaration d'espace de nom personnalisé pour la classe personnalisée dans la déclaration d'espace de nom XSLT (dans un fichier XSLT)

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

3) Passez une instance de l'objet personnalisé à XSLT, avec le même espace de nom que lors de la dernière étape (en C #)

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

4) Utilisez l'objet depuis XSLT (dans un fichier XSLT)

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

Exemple de code

Pour notre exemple, supposons que nous ayons une feuille XSLT dans laquelle nous devons manipuler des dates. Nous devons indiquer le nombre de jours que l'employé a passé dans l'entreprise. Puisque XSLT n’a pas de fonction de manipulation de date native, utilisons un objet extension pour notre tâche.

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() ;
    }

}

Compilez ce code et utilisez les fichiers members.xml et memberdisplay.xsl fournis pour exécuter cette application console. Vous devriez voir un fichier extendXSLT.html dans le même dossier. Ouvrez ce fichier et notez que notre classe CustomDate a été appelée pour calculer le nombre de jours que l'employé a passé dans l'entreprise.

Résumé:
XSLT est un puissant langage de transformation pour XML. Toutefois, l'utilisation d'objets d'extension dans .NET et C # devrait permettre de réaliser facilement ce qui serait impossible ou difficile avec XSLT seul.

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

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

Lorsque vous parlez de la prise en charge .NET de XSLT 2.0, XPath 2.0 et XQuery 1.0, il est important de faire la distinction entre les langues elles-mêmes et le modèle de données (XDM). Le .NET 3.5 Framework prend en charge le modèle de données, mais pas les langues. Comme cela m'a été récemment expliqué par courrier électronique, Pawel Kadluczka, de Microsoft:

  

La phrase " instances de XQuery   Modèle de données 1.0 et XPath 2.0 " peut être déroutant, mais je crois qu'il fait référence à   Données W3C XQuery 1.0 et XPath 2.0   Modèle (XDM)   ( http://www.w3.org/TR/xpath-datamodel )   qui se lit comme suit:

     

[Définition: chaque instance de   le modèle de données est une séquence.].

     

[Définition: une séquence est un ordre   collection de zéro ou plusieurs articles.]   séquence ne peut pas être membre d'un   séquence. Un seul élément apparaissant sur   son propre est modélisé comme une séquence   contenant un article. Les séquences sont   défini dans 2.5 séquences.

     

[Définition: un élément est soit un nœud   ou une valeur atomique],

     

Dans le cas de l'API XPath -   XPathNodeIterator est la séquence   tandis que XPathItem (XPathNavigator)   représente l'élément.

Oui, XPathNavigator 3.5 prend en charge XSLT 2.0.

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

"La classe XPathNavigator de l'espace de noms System.Xml.XPath est une classe abstraite qui définit un modèle de curseur pour la navigation et la modification d'éléments d'information XML en tant qu'instances du modèle de données XQuery 1.0 et XPath 2.0."

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top