Question de débutant XSLT : veuillez remplir le champ vide dans le fragment de code C# ci-dessous :

public static string TransformXMLToHTML(string inputXml, string xsltString) {
  // insert code here to apply the transform specified by xsltString to inputXml 
  // and return the resultant HTML string.
  // You may assume that the xslt output type is HTML.
}

Merci!

21
Shaul Behr 22 nov. 2009 à 12:48

2 réponses

Meilleure réponse

Que diriez-vous:

public static string TransformXMLToHTML(string inputXml, string xsltString)
{
    XslCompiledTransform transform = new XslCompiledTransform();
    using(XmlReader reader = XmlReader.Create(new StringReader(xsltString))) {
        transform.Load(reader);
    }
    StringWriter results = new StringWriter();
    using(XmlReader reader = XmlReader.Create(new StringReader(inputXml))) {
        transform.Transform(reader, null, results);
    }
    return results.ToString();
}

Notez qu'idéalement, vous devriez mettre en cache et réutiliser le XslCompiledTransform - ou peut-être utiliser XslTransform à la place (cependant, il est marqué comme obsolète).

41
Marc Gravell 22 nov. 2009 à 12:59
Marc, tu es un prince parmi les hommes. :)
 – 
Shaul Behr
22 nov. 2009 à 13:08
Très soigné et simple.
 – 
Chris
28 août 2013 à 13:23
2
Eh bien, cela peut devenir plus simple que cela. Tous ces lecteurs XML peuvent être remplacés par l'emplacement réel des fichiers comme : XslCompiledTransform transform = new XslCompiledTransform("file://"+xsltString); Transform a également une version dans laquelle vous pouvez transmettre l'emplacement du fichier en utilisant cette astuce "file://" + inputXml ;)
 – 
tecfield
21 nov. 2014 à 18:46

Pour le fun, une version un peu moins élégante qui implémente la mise en cache suggérée par Marc :

    public static string TransformXMLToHTML(string inputXml, string xsltString)
    {
        XslCompiledTransform transform = GetAndCacheTransform(xsltString);
        StringWriter results = new StringWriter();
        using (XmlReader reader = XmlReader.Create(new StringReader(inputXml)))
        {
            transform.Transform(reader, null, results);
        }
        return results.ToString();
    }

    private static Dictionary<String, XslCompiledTransform> cachedTransforms = new Dictionary<string, XslCompiledTransform>();
    private static XslCompiledTransform GetAndCacheTransform(String xslt)
    {
        XslCompiledTransform transform;
        if (!cachedTransforms.TryGetValue(xslt, out transform))
        {
            transform = new XslCompiledTransform();
            using (XmlReader reader = XmlReader.Create(new StringReader(xslt)))
            {
                transform.Load(reader);
            }
            cachedTransforms.Add(xslt, transform);
        }
        return transform;
    }
4
Dathan 22 nov. 2009 à 13:13
Vous auriez à vous soucier de la sécurité des threads / de la synchronisation autour du dictionnaire, mais quelque chose dans ce sens, oui.
 – 
Marc Gravell
22 nov. 2009 à 14:04
Et il me vient à l'esprit qu'il pourrait être intéressant de hacher le xsltString et d'utiliser ce hachage comme clé à la place. Certaines transformations peuvent devenir assez volumineuses - aucune raison d'encourir la pénalité de mémoire supplémentaire en la stockant sous forme compilée dans le XslCompiledTransform et à nouveau en tant que clé.
 – 
Dathan
24 nov. 2009 à 05:30