2010-01-11 42 views
10

Tôi có đoạn mã sau đó áp dụng một phong cách XSLTChrome và Safari XSLT sử dụng 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); 
     } 
    } 

Mã này được làm việc trong IE và firefox nhưng không có trong Chrome và Safari. Bất kỳ ý tưởng tại sao?

Cập nhật

ResultDocument = xsltProcessor.transformToFragment(xml, document); 

Dòng trên là trở về null. Không có lỗi nào đang được ném.

Cập nhật

Mã này không hoạt động như các tập tin XSLT chứa xsl: include. Cần phải tìm một cách để có được bao gồm làm việc tôi sẽ dán tiến bộ ở đây

Cập nhật

Nó đã được khuyến cáo mà tôi sử dụng plugin http://plugins.jquery.com/project/Transform/. Tôi đang cố gắng sử dụng thư viện phụ của khách hàng làm ví dụ về việc bao gồm các công trình ở đây (http://daersystems.com/jquery/transform/).

Mã hoạt động trong IE nhưng vẫn không có trong chrome.

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 và xsl là cả hai đối tượng được thông qua tại.

Cập nhật

Tôi đã cố gắng thay đổi các tập tin XSL để trở thành một cái gì đó rất đơn giản không có bao gồm và Chrome vẫn chưa được áp dụng các stylesheet và IE là. XSL đang được đưa vào như một đối tượng là:

<?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> 

Cập nhật

Kết quả cuối cùng mà tôi muốn là cho xsl được áp dụng cho các tập tin xml. Tệp xsl có trong nó bao gồm. Tôi muốn trasnfer xảy ra trên máy khách một cách lý tưởng.

Đã cập nhật Rupert bạn có thể cập nhật câu hỏi bằng xml và cách bạn đang gọi Test.Xml.xslTransform không?

tôi đã xml sử dụng 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> 

Mã này đã được gọi như sau:

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

xdata là xml trả về bởi một dịch vụ web.

+0

Vui lòng cung cấp thêm thông tin, chẳng hạn như thông báo ngoại lệ. Tôi khuyên bạn nên sử dụng Sarissa (JavaScript nguồn mở cho XML/XSLT trên nhiều trình duyệt). –

+0

Có lẽ XSLT trên XML không trả lại kết quả vì không có mẫu nào trong kết hợp XSLT trên tài liệu XML. Xem blog của tôi "Tránh các lỗi XSLT phổ biến" (http://dev.ektron.com/blogs.aspx?id=22956), đặc biệt là liên kết "XSLT: namespaces" (http://dev.ektron.com/kb_article.aspx ? id = 481) –

+0

Có vẻ như có sự cố khi sử dụng xsl: include trong xslt. Nhìn vào những cách vòng quanh nó vào lúc này. – Rupert

Trả lời

14

Nếu XSLT của bạn đang sử dụng xsl:include bạn có thể nhận được lỗi không thể giải thích lạ nhưng luôn có kết quả cuối cùng: chuyển đổi của bạn không thành công.

Xem báo cáo lỗi crom này và vui lòng hỗ trợ! http://code.google.com/p/chromium/issues/detail?id=8441

Lỗi này thực sự nằm trong webkit. Để biết thêm thông tin here's một liên kết khác đi vào chi tiết hơn tại sao nó không hoạt động.

Cách duy nhất xung quanh việc này là xử lý trước biểu định kiểu để nó chèn các biểu định kiểu đi kèm. Thư viện XSLT crossbrowser như Sarissa sẽ làm gì cho bạn một cách tự động.

Nếu bạn đang tìm giải pháp jQuery:
http://plugins.jquery.com/project/Transform/ là trình cắm thêm XSL của trình duyệt chéo. Tôi đã sử dụng thành công điều này để có được xsl:include làm việc trong quá khứ mà không gặp nhiều rắc rối. Bạn không cần phải viết lại plugin của xsl này sẽ xử lý chúng trước cho bạn. Chắc chắn đáng xem vì nó nhẹ hơn Sarissa.

UPDATE: trang html

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

thử nghiệm này hoạt động cả trong Chrome/FireFox/IE.

input.xml chỉ là một tệp xml đơn giản có chứa <root /> transform.xsl là xsl bị tước bỏ mà bạn đã đăng.

EDIT

Nó tuy nhiên dường như các $ .transform có vấn đề về nhập khẩu stylesheets từ các tập tin bao gồm:

Dưới đây là làm thế nào để sửa lỗi này:

Xác định vị trí

var safariimportincludefix = function(xObj,rootConfig) { 

trong jquery.transform.js và thay thế toàn bộ chức năng bằng cách này:

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

Bây giờ sử dụng thử nghiệm dán trước index.html sử dụng này cho 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> 

Và điều này cho 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> 

Với việc sửa chữa được đăng trước đây trong jquery.transform.js này bây giờ sẽ chèn bao gồm <h1>Test</h1> trên tất cả các trình duyệt.

Bạn có thể nhìn thấy nó trong hành động ở đây: http://www.mpdreamz.nl/xsltest

+0

Dường như vấn đề xsl: include đang gây ra sự cố. Tôi đang xem xét có thể đang cố gắng sử dụng Sarissa – Rupert

+0

Được cập nhật với một thư viện khác nhằm sửa lỗi này. Plugin jQuery rất dễ cài đặt và bạn không phải viết lại xslt's, đây là một công cụ tiết kiệm thời gian rất lớn ngay cả khi quá trình xử lý trước sẽ thêm thời gian chờ. –

+0

Tôi nghĩ rằng vấn đề tôi sẽ có là tập tin xml đang được genereated trên bay vì vậy tôi không nghĩ rằng các chức năng biến đổi sẽ làm việc – Rupert

5

Đây không phải là một câu trả lời cho câu hỏi ban đầu nhưng trong quá trình tìm kiếm của tôi trên internet tìm kiếm một chuyển đổi XSLT mẫu hoạt động trên chrome tôi thấy các liên kết đến chủ đề này nhiều lần. Tôi đang tìm một giải pháp không sử dụng bất kỳ thư viện/trình cắm nguồn mở hoặc bên thứ ba nào và hoạt động tốt với Silverlight.

Sự cố với chrome và safari là giới hạn ngăn không cho tải tệp xml trực tiếp. Giải pháp được đề xuất tại http://www.mindlence.com/WP/?p=308 là tải tệp xml qua bất kỳ phương thức nào khác và chuyển nó dưới dạng chuỗi cho bộ xử lý xslt.

Với cách tiếp cận này, tôi đã có thể thực hiện các phép biến đổi xsl trong javascript và chuyển kết quả đến ứng dụng Silverlight qua HTML Bridge.

Các vấn đề liên quan