zc2
asked on
Safari's transformToDocument() and xsl:import
Is it possible to make Safari browser's XSLTProcessor properly execute the transformToDocument() method when the XSLT template has an xsl:import element? In my case the method returns nothing.
I have attached a HTML snippet for testing as well as the XML and XSLT files it refers to.
I have attached a HTML snippet for testing as well as the XML and XSLT files it refers to.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<SCRIPT type='text/javascript'>
function testXSL() {
try {
var req = new XMLHttpRequest();
req.open("GET", "empty.xsl", false);
req.send(null);
var xsl = req.responseXML;
if( !xsl ) {
alert("Unable to load xsl!");
return false;
}
alert(new XMLSerializer().serializeToString( xsl.documentElement ));
var xsl_processor = new XSLTProcessor();
xsl_processor.importStylesheet( xsl );
req.open("GET", "empty.xml", false);
req.send(null);
var xml = req.responseXML;
if( !xml ) {
alert("Unable to load xml!");
return false;
}
var result_doc = xsl_processor.transformToDocument( xml );
if( !result_doc ) {
alert("Unable to transform!");
return false;
}
alert(new XMLSerializer().serializeToString(result_doc.documentElement));
}
catch( e ) {
alert("XSLT error: "+e.message + "(" + e + ")");
return false;
}
}
//</SCRIPT>
</HEAD>
<BODY>
<input type="button" value="test XSL" onclick="testXSL();"/>
</BODY>
</HTML>
--- empty.xsl ---
<?xml version="1.0"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:import href="utility_template.xsl"/>
</xsl:stylesheet>
--- empty.xml ---
<root></root>
ASKER
No, absolute path brings the same result.
Is there any possible workaround?
Is there any possible workaround?
that's where the problem comes in. On the XSLT list this matter has been the subject of debate a couple of times. The problem is, you cannot simply create some function that combines the stylesheets and then runs the complete stylesheet. That is because of the import precedence complexities (they would fade away as soon as you combine them) and add to that the apply-imports calls, which wouldn't mean much anymore.
Unfortunately it has been found that expressing xsl:import in one XSLT is actually impossible, apart from the most trivial cases: parse your stylesheet and apply an <xsl:copy-of select="document(xls-impor t/@href)/* /xsl:templ ate" /> (use an xsl ns alias) to every xsl:import statement, recursively. The resulting XSLT XML document can then be used for XSLT processing. But you'll loose much of the xsl:import functionality this way.
If I have some time tomorrow I'll try to dig up some comments of Chrome/Safari developers on the subject. Maybe they've some timeline for a fix, but so far I haven't seen much in that direction.
-- Abel --
Unfortunately it has been found that expressing xsl:import in one XSLT is actually impossible, apart from the most trivial cases: parse your stylesheet and apply an <xsl:copy-of select="document(xls-impor
If I have some time tomorrow I'll try to dig up some comments of Chrome/Safari developers on the subject. Maybe they've some timeline for a fix, but so far I haven't seen much in that direction.
-- Abel --
ASKER
Thank you for the advise. But, not matter how hard I try, the document() function returns an empty document.
just a question intermittently, but are the urls relative to the current url? Are they higher or lower up the path hierarchy? Can you give an example of your urls from the main .html (or .jsp/.aspx), the .js holding the XSLT transform code (if any) and the *.xslt files (incl the imported ones)?
It looks very much like a similar issue that I had before, it would help if I knew how exactly you are building the xslt and from where (and yes, I saw the code above).
It looks very much like a similar issue that I had before, it would help if I knew how exactly you are building the xslt and from where (and yes, I saw the code above).
ASKER
ASKER
I'm sorry, sent the last comment before actually write it.
What you see in the previous comment is the result I see in a firefox browser.
In a webkit based browser (Chrome, Safari 4) the result is only
<a>((((())))</a>
The attached file in the previous comment is a .tar archive with the files I use for the testing.
testxsl_doc.htm - main file, open it in the browser, then click the button.
doc.xsl - an XSLT using the document() function
empty.xml - empty xml which document() tries to access
0.xml - another empty xml to make the transformation with.
What you see in the previous comment is the result I see in a firefox browser.
In a webkit based browser (Chrome, Safari 4) the result is only
<a>((((())))</a>
The attached file in the previous comment is a .tar archive with the files I use for the testing.
testxsl_doc.htm - main file, open it in the browser, then click the button.
doc.xsl - an XSLT using the document() function
empty.xml - empty xml which document() tries to access
0.xml - another empty xml to make the transformation with.
I started out getting other results, but now I'm on the same page as you. Just for argument's sake, I put some screenshots here to make sure we all agree on the differences.
ScreenShot209.png
ScreenShot210.png
ScreenShot208.png
ScreenShot207.png
ScreenShot206.png
ScreenShot209.png
ScreenShot210.png
ScreenShot208.png
ScreenShot207.png
ScreenShot206.png
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thank you for the great work you did. It seems I need just to disable the ajax functionality for that kind of browsers at least for a while.
If there any news how to make the xsl:import work, please let me know, I'll very appreciate that.
If there any news how to make the xsl:import work, please let me know, I'll very appreciate that.
glad I could be of some help :)
See the second post here: http://ajaxandxml.blogspot.com/search/label/Chrome which is about disabling XSLT for chrome.
I just downloaded the Chrome source to see why it is not executing the code above. I'll let you know if I find something useful. I checked the (advanced) security settings and widened them, but that did not yield any results.
See the second post here: http://ajaxandxml.blogspot.com/search/label/Chrome which is about disabling XSLT for chrome.
I just downloaded the Chrome source to see why it is not executing the code above. I'll let you know if I find something useful. I checked the (advanced) security settings and widened them, but that did not yield any results.
ASKER
Thank you. But is there simpler way to detect a webkit based browser?
if (navigator.userAgent.toLow erCase().i ndexOf('we bkit')!=-1 ) alert('Go upgrade to an XSLT supporting browser')
ASKER
:)
Thank you.
Thank you.
Hi zc2,
I know you closed this question, but you asked me to update if I knew something more. These days I played a bit with the source code of Chrome (quite a bit of a piece of code, btw) and tried to find the point of error and/or a workaround.
Unfortunately, the place in the code where XSLT is resolving external documents (id. for xsl:import/include) does never run. It uses an if-statement that is supposed to check the validity of the URL, but because of negligence of the programmers, they forgot to give it a context-frame, which is necessary for that piece of code to return true (i.e., valid).
End of the story: it is a bug, and quite a major one. They do have all the code there to make it work, but due to this bug it doesn't work. I changed the code a bit and managed to get it working without too much efforts. Here's a screenshot of a beta-build with modified source that runs your code correctly:
ScreenShot213.png
I know you closed this question, but you asked me to update if I knew something more. These days I played a bit with the source code of Chrome (quite a bit of a piece of code, btw) and tried to find the point of error and/or a workaround.
Unfortunately, the place in the code where XSLT is resolving external documents (id. for xsl:import/include) does never run. It uses an if-statement that is supposed to check the validity of the URL, but because of negligence of the programmers, they forgot to give it a context-frame, which is necessary for that piece of code to return true (i.e., valid).
End of the story: it is a bug, and quite a major one. They do have all the code there to make it work, but due to this bug it doesn't work. I changed the code a bit and managed to get it working without too much efforts. Here's a screenshot of a beta-build with modified source that runs your code correctly:
ScreenShot213.png
ASKER
Great job! You're really a genius!!
Did you submit the issue to developers?
If they going to fix it both in Safari and Chromium, I'm willing to wait until the new version will come.
Thank you again very much!
Did you submit the issue to developers?
If they going to fix it both in Safari and Chromium, I'm willing to wait until the new version will come.
Thank you again very much!
I don't know enough of the intricacies involved to know whether bullying with these settings and code might have some waterfall effect on something else. Of course I can point them to the problem (and I will) and a possible direction for the solution. The only related bug issue that I could find so far is currently this one, and it only touches at the issue.
-- Abel --
-- Abel --
ASKER
I hope they will respond and fix the bug.
Quite a while ago I posted a fix for a similar issue for the Sarissa cross-browser XSLT library, which was related to relative paths and *.js files, where IE and other browsers interpreted the base path differently. If a path problem may be the cause of your issue, you can test that by applying an absolute path to see if that makes a difference.
-- Abel --