使用JavaScript的Chrome和Safari XSLT [英] Chrome and Safari XSLT using JavaScript
问题描述
我有以下适用于XSLT风格的代码
Test.Xml.xslTransform = function(xml,xsl){
try {
//代码为IE
if(window.ActiveXObject){
ex = xml.transformNode(xsl);
return ex;
}
// Mozilla,Firefox,Opera等的代码
else if(document.implementation&& document.implementation.createDocument){
xsltProcessor = new XSLTProcessor ();
xsltProcessor.importStylesheet(xsl);
resultDocument = xsltProcessor.transformToFragment(xml,document);
返回resultDocument; (例外){
}
} catch(例外){
if(typeof(exception)==object){
if(exception.message){
alert 。信息);
}
} else {
alert(exception);
code
这段代码在IE和firefox中工作,但不在Chrome和Safari。任何想法为什么?
更新
ResultDocument = xsltProcessor.transformToFragment(xml,document);
上面的行返回null。没有错误发生。
更新
xslt文件包含xsl:include。需要找到一种方法来获得包括工作我会在这里粘贴进度
更新
建议我使用 http://plugins.jquery.com/project/Transform / 插件。我正在尝试使用客户端库文件作为包含在此作品的示例( http://daersystems.com/jquery / b>
这段代码在IE中运行,但仍然不在chrome中。
Test.Xml.xslTransform = function(xml,xsl){
try {
$(body)。append(< div id ='test'风格= '显示:无;' >< / DIV>中);
var a = $(#test)。transform({xmlobj:xml,xslobj:xsl});
返回a.html(); (例外){
如果(例外)==object){
if(exception.message){
alert(例外)信息);
}
} else {
alert(exception);
}
}
}
xml和xsl都是传入的对象。
更新
XSL文件是非常简单的东西,没有包含和Chrome仍然没有应用样式表和IE浏览器。作为对象引入的XSL是:
<?xml version =1.0encoding =utf- 8\" >?;
xmlns:xsl =http://www.w3.org/1999/XSL/Transform
xmlns:rs =urn: schemaset-microsoft-com:rowset
xmlns:z =#RowsetSchema
xmlns:soap =http://schemas.xmlsoap.org/soap/envelope/
xmlns: msxsl =urn:schemas-microsoft-com:xsltexclude-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>测试< / h1>
< / xsl:template>
< / xsl:stylesheet>
更新
我想要的最终结果是将xsl应用于xml文件。其中包含xsl文件。我希望trasnfer能在客户端发生。
更新
Rupert可以使用xml更新问题以及如何调用Test.Xml.xslTransform?
我使用ie8获得了xml
<?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-00AA00C14882xmlns:dt =uuid:C2F41010-65B3-11d1-A29F-00AA00C14882xmlns:rs =urn:schemas- microsoft-com:rowsetxmlns:z =#RowsetSchema>
< rs:data ItemCount =1>
< / rs:data>
< / listitems>< / SearchListItemsResult>< / SearchListItemsResponse>< / soap:Body>< / soap:Envelope>
代码被调用如下:
xsl = Test.Xml.loadXMLDoc(/ _ layouts / xsl / xsl.xslt);
var doc = Test.Xml.xslTransform(xData.responseXML,xsl);
xData是Web服务返回的xml。
看到这个铬错误报告,请支持!
http://code.google.com/p/chromium / issues / detail?id = 8441
这个错误实际上是在webkit中。有关更多信息,请参见此处另一个链接,详细介绍为什么它不起作用。
解决这个问题的唯一方法是预处理样式表,以便注入包含的样式表。这就是像Sarissa这样的交叉浏览器XSLT库会自动为你做的。
如果你正在寻找jQuery解决方案:
http://plugins.jquery.com/project/Transform/ 是一个跨浏览器的XSL插件。我已经成功地使用它来获得 xsl:include
在过去没有太多麻烦。你不必重写你的xsl,这个插件会为你预先处理它们。绝对值得一看,因为它比Sarissa更轻量。
更新:
< HTML>
< head>
< script language =javascriptsrc =jquery-1.3.2.min.js>< / script>
< script language =javascriptsrc =jquery.transform.js>< / script>
< script type =text / javascript>
函数loadXML(文件)
{
var xmlDoc = null;
尝试// Internet Explorer
{
xmlDoc = new ActiveXObject(Microsoft.XMLDOM);
xmlDoc.async = false;
xmlDoc.load(file);
catch(e)
{
尝试// Firefox,Mozilla,Opera等
{
xmlDoc = document.implementation.createDocument( ,,空值);
xmlDoc.async = false;
xmlDoc.load(file);
catch(e)
{
尝试// 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;
函数xslTransform(xmlObject,xslObject)
{
try
{
$(body)。append(< div id = '测试' >< / DIV>中);
var a = $(#test)。transform({xmlobj:xmlObject,xslobj:xslObject});
}
catch(例外)
{
if(typeof(exception)==object&& exception.message)
alert(exception.message );
其他警报(例外);
}
}
var xmlObject = loadXML(input.xml);
var xslObject = loadXML(transform.xsl);
$(document).ready(function()
{
xslTransform(xmlObject,xslObject);
});
< / script>
< / head>
< body>
< / body>
< / html>
这个测试html页面可以在Chrome / FireFox / IE中使用。
input.xml只是一个简单的xml文件,其中包含< root />
转换。 xsl是您发布的精简版xsl。
编辑 然而,
以下是解决此问题的方法:
定位
var safariimportincludefix = function(xObj,rootConfig){
位于 jquery.transform.js
中,并用此替换整个函数:
var safariimportincludefix = function(xObj,rootConfig){
var vals = $ .merge($。makeArray(xObj.getElementsByTagName(import)),$ .makeArray(xObj.getElementsByTagName( 包含)));
(var x = 0; x var node = vals [x]; $ b $ .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(例外)
{
var x =异常;
}
var existingNames = [];
var existingMatches = []; (existingNodes [a] .getAttribute(name)){
existingNames [existingNodes [a])的
(var a = 0; a< existingNodes.length; 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;
};
现在使用先前粘贴的测试index.html将它用于 transform.xsl
:
<?xml version =1.0encoding =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>
对于 include.xsl
<?xml version =1.0encoding =utf-8?>
< xsl:stylesheet version =1.0xmlns:xsl =http://www.w3.org/1999/XSL/Transform>
< xsl:template name =giveMeAnIncludedHeader>
< h1>测试< / h1>
< / xsl:template>
< / xsl:stylesheet>
通过之前在 你可以在这里看到它: http://www.mpdreamz.nl/xsltest I have the following code that applies a XSLT style The code is working in IE and firefox but not in Chrome and Safari. Any ideas why? Update The line above is returning null. No error is being thrown. Update The code is not working as the xslt file contains xsl:include. Need to find a way to get the include working I will paste progress here Update It has been recomended that I use the http://plugins.jquery.com/project/Transform/ plugin. I am trying to use the client side libary as the example of include works here (http://daersystems.com/jquery/transform/). The code works in IE but still not in chrome. xml and xsl are both objects being passed in. Update I tried changing the XSL file to being something very simple with no include and Chrome is still not applying the stylesheet and IE is. The XSL that is being brought in as an object is: Update The end result that I want is for the xsl to be applied to the xml file. The xsl file has in it includes. I want the trasnfer to happen on the client ideally. Updated
Rupert could you update the question with the xml and how you're calling Test.Xml.xslTransform ? I got the xml using ie8 The code is being called as follows: xData is the xml returned by a web service. If your XSLT is using See this chromium bug report and please support it!
http://code.google.com/p/chromium/issues/detail?id=8441 The bug is actually in webkit though. For more info here's another link which goes into more detail why it doesn't work. The only way around this is to pre-process the stylesheet so that it injects the included stylesheets. Which is what a crossbrowser XSLT library like Sarissa will do for you automatically. If your looking for jQuery solution: UPDATE: This test html page works both in Chrome/FireFox/IE. input.xml is just a simple xml file containing EDIT It does however seem the $.transform has problems importing stylesheets from included files: Here's how to fix this: Locate in Now using the previously pasted test index.html use this for And this for With the previously posted fix in You can see it in action here: http://www.mpdreamz.nl/xsltest 这篇关于使用JavaScript的Chrome和Safari XSLT的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! jquery.transform.js $ c中发布的修复$ c>现在将在所有浏览器中插入包含的
< h1> Test< / h1>
。
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);
}
}
ResultDocument = xsltProcessor.transformToFragment(xml, document);
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 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>
<?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>
xsl = Test.Xml.loadXMLDoc("/_layouts/xsl/xsl.xslt");
var doc = Test.Xml.xslTransform(xData.responseXML, xsl);
xsl:include
you might receive weird unexplainable errors but always with the same end result: your transformation failing.
http://plugins.jquery.com/project/Transform/ is a cross browser XSL plug-in. I've succesfully used this to get xsl:include
working in the past without much hassle. You don't have to rewrite your xsl's this plugin will pre-process them for you. Definitely worth looking at as it's more lightweight then 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>
<root />
transform.xsl is the stripped down xsl you posted.var safariimportincludefix = function(xObj,rootConfig) {
jquery.transform.js
and replace the entire function with this: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;
};
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>
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>
jquery.transform.js
this will now insert the included <h1>Test</h1>
on all the browsers.