11 votes

Chrome et Safari XSLT en utilisant JavaScript

J'ai le code suivant qui applique un style XSLT

Test.Xml.xslTransform = function(xml, xsl) {
    try {
        // code pour IE
        if (window.ActiveXObject) {
            ex = xml.transformNode(xsl);
            return ex;
        }
        // code pour Mozilla, Firefox, Opera, etc.
        else if (document.implementation && document.implementation.createDocument) {
            xsltProcessor = new XSLTProcessor();
            xsltProcessor.importStylesheet(xsl);
            resultDocument = xsltProcessor.transformToFragment(xml, document);
            return resultDocument;
        }
    } catch (exception) {
        if (typeof (exception) == "object") {
            if (exception.message) {
                alert(exception.message);
            }
        } else {
            alert(exception);
        }
    }

Le code fonctionne dans IE et Firefox mais pas dans Chrome et Safari. Des idées pourquoi?

Mise à jour

ResultDocument = xsltProcessor.transformToFragment(xml, document);

La ligne ci-dessus retourne null. Aucune erreur n'est lancée.

Mise à jour

Le code ne fonctionne pas car le fichier xslt contient xsl:include. Besoin de trouver un moyen de faire fonctionner l'inclusion. Je vais coller l'avancement ici

Mise à jour

Il a été recommandé d'utiliser le http://plugins.jquery.com/project/Transform/ plugin. J'essaie d'utiliser la librairie côté client car l'exemple d'inclusion fonctionne ici (http://daersystems.com/jquery/transform/).

Le code fonctionne dans IE mais toujours pas dans Chrome.

Test.Xml.xslTransform = function(xml, xsl) {
        try {
                $("body").append("");
                var a = $("#test").transform({ xmlobj: xml, xslobj: xsl });
                return a.html();
        }
        catch (exception) {
            if (typeof (exception) == "object") {
                if (exception.message) {
                    alert(exception.message);
                }
            } else {
                alert(exception);
            }

        }
    }

xml et xsl sont tous deux des objets passés en paramètres.

Mise à jour

J'ai essayé de changer le fichier XSL pour quelque chose de très simple sans inclusion et Chrome n'applique toujours pas la feuille de style et IE si. Le XSL qui est apporté en tant qu'objet est:

        test

Mise à jour

Le résultat final que je veux est que le xsl soit appliqué au fichier xml. Le fichier xsl contient des inclusions. Je veux que le transfert se fasse de préférence côté client.

Updated Rupert pourrais-tu mettre à jour la question avec le xml et comment tu appelles Test.Xml.xslTransform ?

J'ai obtenu le xml en utilisant ie8

Le code est appelé comme suit:

xsl = Test.Xml.loadXMLDoc("/_layouts/xsl/xsl.xslt");
var doc = Test.Xml.xslTransform(xData.responseXML, xsl);

xData est le xml retourné par un service web.

14voto

Martijn Laarman Points 8097

Si votre XSLT utilise xsl:include vous pourriez rencontrer des erreurs étranges inexplicables mais toujours avec le même résultat final : l'échec de votre transformation.

Voir ce rapport de bug chromium et veuillez le soutenir ! http://code.google.com/p/chromium/issues/detail?id=8441

Le bug est en réalité dans webkit. Pour plus d'informations voici un autre lien qui explique en détail pourquoi cela ne fonctionne pas.

La seule solution à ce problème est de prétraiter la feuille de style afin d'injecter les feuilles de style incluses. Ceci est ce qu'une bibliothèque XSLT multi-navigateurs comme Sarissa fera automatiquement pour vous.

Si vous cherchez une solution jQuery :
http://plugins.jquery.com/project/Transform/ est un plug-in XSL multi-navigateurs. J'ai utilisé avec succès cela pour faire fonctionner xsl:include dans le passé sans trop de tracas. Vous n'avez pas à réécrire vos fichiers xsl, ce plugin les prétraitera pour vous. Cela vaut vraiment la peine d'y jeter un coup d'œil car c'est plus léger que Sarissa.

MISE À JOUR:

function loadXML(file)
{
    var xmlDoc = null;
    try //Internet Explorer
    {
        xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
        xmlDoc.async=false;
        xmlDoc.load(file);
    }
    catch(e)
    {
        try //Firefox, Mozilla, Opera, etc.
        {
            xmlDoc=document.implementation.createDocument("","",null);
            xmlDoc.async=false;
            xmlDoc.load(file);
        }
        catch(e)
        {
            try //Google Chrome
            {
                var xmlhttp = new window.XMLHttpRequest();
                xmlhttp.open("GET",file,false);
                xmlhttp.send(null);
                xmlDoc = xmlhttp.responseXML.documentElement;
            }
            catch(e)
            {
            error=e.message;
            }
        }
    }
    return xmlDoc;
}
function xslTransform(xmlObject, xslObject)
{
    try 
    {
        $("body").append("<div id='test'></div>");
        var a = $("#test").transform({ xmlobj: xmlObject, xslobj: xslObject });
    }
    catch (exception) 
    {
        if (typeof (exception) == "object" && exception.message) 
            alert(exception.message);
        else alert(exception);
    }
}
var xmlObject = loadXML("input.xml");
var xslObject = loadXML("transform.xsl");
$(document).ready(function()  
{
    xslTransform(xmlObject, xslObject);
});

Cette page html de test fonctionne à la fois dans Chrome/FireFox/IE.

input.xml est juste un fichier xml simple contenant transform.xsl est la feuille de style simplifiée que vous avez postée.

MODIFICATION

Il semble cependant que $.transform ait des problèmes pour importer des feuilles de style à partir de fichiers inclus :

Voici comment résoudre ce problème :

Localisez

var safariimportincludefix = function(xObj,rootConfig) {

dans jquery.transform.js et remplacez toute la fonction par ceci :

var safariimportincludefix = function(xObj,rootConfig) {
    var vals = $.merge($.makeArray(xObj.getElementsByTagName("import")),$.makeArray(xObj.getElementsByTagName("include")));

    for(var x=0;x

``

Maintenant, en utilisant le fichier index.html de test précédemment collé, utilisez ceci pour transform.xsl :

Et ceci pour include.xsl

        Test

Avec la correction précédemment postée dans jquery.transform.js ceci insérera maintenant le

Test

inclus sur tous les navigateurs.

Vous pouvez le voir en action ici : http://www.mpdreamz.nl/xsltest

``

5voto

moonlightdock Points 782

Ce n'est pas une réponse à la question originale mais lors de mes recherches sur internet à la recherche d'une transformation xslt d'échantillon qui fonctionne sur Chrome, j'ai trouvé des liens vers ce fil de discussion plusieurs fois. Je cherchais une solution qui n'utilise pas de bibliothèques/plugins open-source ou tiers et qui fonctionne bien avec Silverlight.

Le problème avec Chrome et Safari est la limitation qui empêche de charger directement des fichiers XML. La solution de contournement suggérée à http://www.mindlence.com/WP/?p=308 est de charger le fichier XML via un autre méthode et de le passer en tant que chaîne au processeur XSLT.

Avec cette approche, j'ai pu effectuer des transformations xsl en javascript et transmettre le résultat à l'application Silverlight via le pont HTML.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X