Rup*_*ert 11 javascript xslt safari jquery google-chrome
我有以下代码应用XSLT样式
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);
}
}
Run Code Online (Sandbox Code Playgroud)
该代码适用于IE和Firefox,但不适用于Chrome和Safari.有什么想法吗?
更新
ResultDocument = xsltProcessor.transformToFragment(xml, document);
Run Code Online (Sandbox Code Playgroud)
上面的行返回null.没有错误被抛出.
更新
由于xslt文件包含xsl:include,因此代码无效.需要找到一种方法来使包含工作我将在此处粘贴进度
更新
我建议使用http://plugins.jquery.com/project/Transform/插件.我正在尝试使用客户端libary作为include的示例(http://daersystems.com/jquery/transform/).
该代码适用于IE,但仍然不在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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
xml和xsl都是传入的对象.
更新
我尝试将XSL文件更改为非常简单但没有包含的内容,Chrome仍未应用样式表和IE.作为对象引入的XSL是:
<?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>
Run Code Online (Sandbox Code Playgroud)
更新
我想要的最终结果是将xsl应用于xml文件.xsl文件包含在其中.我希望trasnfer理想地发生在客户端上.
更新了 Rupert你可以用xml更新问题以及你如何调用Test.Xml.xslTransform?
I got the xml using 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>
Run Code Online (Sandbox Code Playgroud)
The code is being called as follows:
xsl = Test.Xml.loadXMLDoc("/_layouts/xsl/xsl.xslt");
var doc = Test.Xml.xslTransform(xData.responseXML, xsl);
Run Code Online (Sandbox Code Playgroud)
xData is the xml returned by a web service.
Mar*_*man 14
如果您的XSLT正在使用,xsl:include您可能会收到奇怪的无法解释的错误,但始终具有相同的最终结果:您的转换失败.
看到这个铬虫报告,请支持它! http://code.google.com/p/chromium/issues/detail?id=8441
该bug实际上是在webkit中.有关更多信息,请参阅另一个链接,详细说明为什么它不起作用.
解决这个问题的唯一方法是预处理样式表,以便它注入包含的样式表.这是像Sarissa这样的crossbrowser XSLT库会自动为您做什么.
如果您正在寻找jQuery解决方案:
http://plugins.jquery.com/project/Transform/是一个跨浏览器的XSL插件.我成功地使用它来xsl:include过去工作而没有太多麻烦.你没有必要重写你的xsl,这个插件会为你预先处理它们.绝对值得一看,因为它比Sarissa更轻巧.
更新:
<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>
Run Code Online (Sandbox Code Playgroud)
此测试html页面适用于Chrome/FireFox/IE.
input.xml只是一个包含<root />
transform.xsl 的简单xml文件,是你发布的精简版xsl.
编辑
但是,似乎$ .transform在从包含的文件导入样式表时遇到问题:
以下是解决此问题的方法:
定位
var safariimportincludefix = function(xObj,rootConfig) {
Run Code Online (Sandbox Code Playgroud)
in jquery.transform.js并用以下内容替换整个函数:
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;
};
Run Code Online (Sandbox Code Playgroud)
现在使用以前粘贴的测试index.html,将其用于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>
Run Code Online (Sandbox Code Playgroud)
这是为了 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>
Run Code Online (Sandbox Code Playgroud)
通过之前发布的修复,jquery.transform.js现在将插入<h1>Test</h1>所有浏览器中的包含.
你可以在这里看到它:http://www.mpdreamz.nl/xsltest
这不是原始问题的答案,但在我通过互联网搜索期间寻找适用于chrome的示例xslt转换时,我发现了多次链接到此线程.我一直在寻找一种不使用任何开源或第三方库/插件的解决方案,并且与Silverlight配合得很好.
chrome和safari的问题是阻止直接加载xml文件的限制.http://www.mindlence.com/WP/?p=308上建议的解决方法是通过任何其他方法加载xml文件,并将其作为字符串传递给xslt处理器.
通过这种方法,我能够在javascript中执行xsl转换,并通过HTML Bridge将结果传递给silverlight应用程序.