Monday, June 3, 2024
 Popular · Latest · Hot · Upcoming
189
rated 0 times [  191] [ 2]  / answers: 1 / hits: 22267  / 15 Years ago, mon, january 11, 2010, 12:00:00

I have the following code that applies a XSLT style



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


The code is working in IE and firefox but not in Chrome and Safari. Any ideas why?



Update



ResultDocument = xsltProcessor.transformToFragment(xml, document);


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.



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



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


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



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


The code is being called as follows:



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


xData is the xml returned by a web service.


More From » jquery

 Answers
66

If your XSLT is using xsl:include you might receive weird unexplainable errors but always with the same end result: your transformation failing.



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:

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.



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>


This test html page works both in Chrome/FireFox/IE.



input.xml is just a simple xml file containing <root />
transform.xsl is the stripped down xsl you posted.



EDIT



It does however seem the $.transform has problems importing stylesheets from included files:



Here's how to fix this:



Locate



var safariimportincludefix = function(xObj,rootConfig) {


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


Now using the previously pasted test index.html use this for 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>


And this for 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>


With the previously posted fix in jquery.transform.js this will now insert the included <h1>Test</h1> on all the browsers.



You can see it in action here: http://www.mpdreamz.nl/xsltest


[#97865] Friday, January 8, 2010, 15 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
georgeh

Total Points: 193
Total Questions: 103
Total Answers: 111

Location: United States Minor Outlying Island
Member since Sat, May 28, 2022
2 Years ago
georgeh questions
Fri, Oct 8, 21, 00:00, 3 Years ago
Tue, Jan 5, 21, 00:00, 3 Years ago
Wed, Nov 25, 20, 00:00, 4 Years ago
Sat, Sep 12, 20, 00:00, 4 Years ago
Sat, Mar 7, 20, 00:00, 4 Years ago
;