2010-01-11 25 views
10

Ich habe folgenden Code, der einen XSLT-StyleChrome und Safari XSLT mit JavaScript

Test.Xml.xslTransform = function(xml, xsl) { 
    try { 
     // code for IE 
     if (window.ActiveXObject) { 
      ex = xml.transformNode(xsl); 
      return ex; 
     } 
     // code for 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); 
     } 
    } 

Der Code funktioniert in IE und Firefox, aber nicht in Chrome und Safari gilt. Irgendwelche Ideen warum?

aktualisieren

ResultDocument = xsltProcessor.transformToFragment(xml, document); 

Die Linie null zurückkehrt oben. Es wird kein Fehler ausgegeben.

aktualisieren

Der Code wird nicht als die XSLT-Datei arbeiten enthält xsl: include. Brauchen Sie noch einen Weg zu finden, das ist zum Laufen bringen werde ich Fortschritte hier

aktualisiert

Paste Es empfohlen wurde, dass ich das http://plugins.jquery.com/project/Transform/ Plugin verwenden. Ich versuche, die clientseitige Bibliothek zu verwenden, da das Beispiel von include hier funktioniert (http://daersystems.com/jquery/transform/).

Der Code funktioniert in IE aber immer noch nicht in Chrom.

Test.Xml.xslTransform = function(xml, xsl) { 
     try { 
       $("body").append("<div id='test' style='display:none;'></div>"); 
       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- und XSL sind beide Objekte in weitergegeben werden.

aktualisieren

Ich habe versucht, die Änderung der XSL-Datei mit nicht etwas sehr einfach zu sein gehören und Chrome ist die Anwendung noch nicht das Stylesheet und IE ist. Die XSL, die als Objekt gebracht wird, ist:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:rs="urn:schemas-microsoft-com:rowset" 
    xmlns:z="#RowsetSchema" 
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:spsoap="http://schemas.microsoft.com/sharepoint/soap/" 
    > 
    <xsl:output method="html"/> 
    <xsl:template match="/"> 
     <h1>test</h1> 
    </xsl:template> 

</xsl:stylesheet> 

aktualisieren

Das Endergebnis, das ich will, ist für die xsl auf die XML-Datei angewendet werden. Die xsl-Datei enthält darin enthalten. Ich möchte den Trasnfer im Idealfall auf dem Client passieren.

Aktualisiert Rupert Sie die Frage mit dem xml aktualisieren können und wie Sie Test.Xml.xslTransform sind nennen?

bekam ich die xml IE8

<?xml version="1.0"?> 
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><SearchListItemsResponse xmlns="http://schemas.microsoft.com/sharepoint/soap/"><SearchListItemsResult><listitems xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema"> 
        <rs:data ItemCount="1"> 
         <z:row ows_Title="Test" ows_FirstName="Test 4" ows_UniqueId="74;#{1A16CF3E-524D-4DEF-BE36-68A964CC24DF}" ows_FSObjType="74;#0" ows_MetaInfo="74;#" ows_ID="74" ows_owshiddenversion="10" ows_Created="2009-12-29 12:21:01" ows_FileRef="74;#Lists/My List Name/74_.000" ReadOnly="False" VerificationRequired="0"/> 
        </rs:data> 
       </listitems></SearchListItemsResult></SearchListItemsResponse></soap:Body></soap:Envelope> 

Der Code wie folgt aufgerufen wird:

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

xData ist die xml von einem Webdienst zurückgegeben.

+0

Geben Sie weitere Informationen an, z. B. die Ausnahmebedingungsnachricht. Ich empfehle Sarissa (Open-Source-JavaScript für browserübergreifendes XML/XSLT) zu verwenden. –

+0

Möglicherweise gibt das XSLT in der XML kein Ergebnis zurück, da keine der Vorlagen in der XSLT mit dem XML-Dokument übereinstimmt. Siehe meinen Blog "Meide häufige XSLT-Fehler" (http://dev.ektron.com/blogs.aspx?id=22956), insbesondere den Link "XSLT: namespaces" (http://dev.ektron.com/kb_article.aspx) ? id = 481) –

+0

Sieht aus wie ein Problem mit xsl: include in der XSLT. Im Moment nach Wegen suchen. – Rupert

Antwort

14

Wenn Ihr XSLT xsl:include verwendet, erhalten Sie möglicherweise seltsame, unerklärliche Fehler, aber immer mit dem gleichen Endergebnis: Ihre Umwandlung schlägt fehl.

Sehen Sie diesen Chrom-Fehlerbericht und bitte unterstützen Sie ihn! http://code.google.com/p/chromium/issues/detail?id=8441

Der Fehler ist eigentlich in Webkit obwohl. Für weitere Informationen here's ein weiterer Link, der mehr ins Detail geht, warum es nicht funktioniert.

Die einzige Möglichkeit besteht darin, das Stylesheet vorzuverarbeiten, so dass es die enthaltenen Stylesheets einfügt. Was wird eine Crossbrowser XSLT-Bibliothek wie Sarissa automatisch für Sie tun? Wenn Sie nach jQuery-Lösung suchen:
http://plugins.jquery.com/project/Transform/ ist ein Cross-Browser-XSL-Plugin. Ich habe es erfolgreich verwendet, um xsl:include in der Vergangenheit ohne viel Aufwand zu arbeiten. Sie müssen Ihre xsl nicht neu schreiben, dieses Plugin wird sie für Sie vorverarbeiten. Auf jeden Fall einen Blick wert, da es leichter ist als Sarissa.

UPDATE:

<html> 
<head> 
<script language="javascript" src="jquery-1.3.2.min.js"></script> 
<script language="javascript" src="jquery.transform.js"></script> 
<script type="text/javascript"> 
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); 
}); 
</script> 
</head> 
<body> 

</body> 
</html> 

Dieser Test HTML-Seite funktioniert sowohl in Chrome/FireFox/IE.

input.xml ist nur eine einfache XML-Datei enthält <root /> Transform.xsl wird die abgespeckte xsl Sie auf dem Laufenden.

EDIT

Es ist jedoch die $ .transform scheint hat Probleme Sheets von eingebundenen Dateien importieren:

Hier ist, wie dieses Problem zu beheben:

Finde

var safariimportincludefix = function(xObj,rootConfig) { 

in jquery.transform.js und ersetzen Sie die gesamte Funktion durch diese:

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

    for(var x=0;x<vals.length;x++) { 
     var node = vals[x]; 
     $.ajax({ 
      passData : { node : node, xObj : xObj, rootConfig : rootConfig}, 
      dataType : "xml", 
      async : false, 
      url : replaceref(node.getAttribute("href"),rootConfig), 
      success : function(xhr) { 
       try { 
        var _ = this.passData; 
        xhr = safariimportincludefix(xhr,_.rootConfig); 

        var imports = $.merge(childNodes(xhr.getElementsByTagName("stylesheet")[0],"param"),childNodes(xhr.getElementsByTagName("stylesheet")[0],"template")); 
        var excistingNodes = []; 
        try 
        { 
         var sheet = _.xObj; 
         var params = childNodes(sheet,"param"); 
         var stylesheets = childNodes(sheet,"template"); 
         existingNodes = $.merge(params,stylesheets); 
        } 
        catch(exception) 
        { 
         var x = exception; 
        } 
        var existingNames = []; 
        var existingMatches = []; 
        for(var a=0;a<existingNodes.length;a++) { 
         if(existingNodes[a].getAttribute("name")) { 
          existingNames[existingNodes[a].getAttribute("name")] = true; 
         } else { 
          existingMatches[existingNodes[a].getAttribute("match")] = true; 
         } 
        } 

        var pn = _.node.parentNode; 
        for(var y=0;y<imports.length;y++) { 
         if(!existingNames[imports[y].getAttribute("name")] && !existingMatches[imports[y].getAttribute("match")]) { 
          var clonednode = _.xObj.ownerDocument.importNode(imports[y],true); 
          //pn.insertBefore(clonednode,_.xObj); 
          pn.insertBefore(clonednode,childNodes(_.xObj,"template")[0]); 
         } 
        } 
        pn.removeChild(_.node); 
       } catch(ex) { 

       } 
      } 
     }); 
    } 

    return xObj; 
}; 

nun mit dem zuvor eingefügten Test diese index.html verwenden für transform.xsl:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    > 
     <xsl:include href="include.xsl" /> 
    <xsl:output method="html"/> 
    <xsl:template match="/"> 
      <xsl:call-template name="giveMeAnIncludedHeader" /> 
    </xsl:template> 
</xsl:stylesheet> 

Und diese für include.xsl

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template name="giveMeAnIncludedHeader"> 
     <h1>Test</h1> 
    </xsl:template> 
</xsl:stylesheet> 

Mit der zuvor gebuchten fix in jquery.transform.js dieser nun fügt das enthaltene <h1>Test</h1> auf allen Browsern.

Sie können es in Aktion sehen hier: http://www.mpdreamz.nl/xsltest

+0

Es scheint das Problem xsl: include zu sein, das das Problem verursacht. Ich versuche, möglicherweise zu versuchen, Sarissa – Rupert

+0

mit einer anderen Bibliothek zu aktualisieren, die darauf abzielt, dies zu beheben. Das jQuery-Plugin ist einfach einzurichten und Sie müssen Ihre xslt's nicht umschreiben, was eine enorme Zeitersparnis bedeutet, auch wenn die Vorverarbeitung etwas Latenz hinzufügen wird. –

+0

Ich denke, das Problem, das ich haben werde, ist, dass die XML-Datei gerade generiert wird, also glaube ich nicht, dass die Transformationsfunktion funktioniert. – Rupert

5

Das ist keine Antwort auf die ursprüngliche Frage, aber während meiner Suche über das Internet für eine Probe XSLT-Transformation suchen, der auf Chrom arbeitet Ich fand Links zu diesem Thema viele Male. Ich war auf der Suche nach einer Lösung, die keine Bibliotheken oder Plugins von Open Source oder Drittanbietern verwendet und gut mit Silverlight funktioniert.

Das Problem mit Chrome und Safari ist die Einschränkung, die das direkte Laden von XML-Dateien verhindert. Die empfohlene Problemumgehung um http://www.mindlence.com/WP/?p=308 besteht darin, die XML-Datei über eine andere Methode zu laden und es als eine Zeichenfolge an den XSLT-Prozessor zu übergeben.

Mit diesem Ansatz konnte ich xsl-Transformationen in Javascript durchführen und das Ergebnis über HTML Bridge an die silverlight app weitergeben.

Verwandte Themen