如何使 XSLT 在 chrome 中工作?

我有一个 XML 文档 给你,它与相应的 XSL 文件一起提供服务。转换将在客户端执行,而不使用 JavaScript。

这在 IE (令人震惊的恐怖)中可以很好地工作,但是在 Google Chrome 中,只显示文档的文本节点。

我知道在 Chrome 中进行客户端 XSL 是可能的,我已经看到了它的例子,但是我还没有能力自己复制这种成功

我做错了什么?

121892 次浏览

At the time of writing, there was a bug in chrome which required an xmlns attribute in order to trigger rendering:

<xsl:stylesheet xmlns="http://www.w3.org/1999/xhtml" ... >

This was the problem I was running into when serving the xml file from a server.


If unlike me, you are viewing the xml file from a file:/// url, then the solutions mentioning --allow-file-access-from-files are the ones you want

Check http://www.aranedabienesraices.com.ar

This site is built with XML/XSLT client-side. It works on IE6-7-8, FF, O, Safari and Chrome. Are you sending HTTP headers correctly? Are you respecting the same-origin policy?

As close as I can tell, Chrome is looking for the header

Content-Type: text/xml

Then it works --- other iterations have failed.

Make sure your web server is providing this. It also explains why it fails for file://URI xml files.

Well it does not work if the XML file (starting by the standard PI:

<?xml-stylesheet type="text/xsl" href="..."?>

for referencing the XSL stylesheet) is served as "application/xml". In that case, Chrome will still download the referenced XSL stylesheet, but nothing will be rendered, as it will silently change the document types from "application/xml" into "Document" (!??) and "text/xsl" into "Stylesheet" (!??), and then will attempt to render the XML document as if it was an HTML(5) document, without running first its XSLT processor. And Nothing at all will be displayed in the screen (whose content will continue to show the previous page from which the XML page was referenced, and will continue spinning the icon, as if the document was never completely loaded.

You can perfectly use the Chrome console, that shows that all resources are loaded, but they are incorrectly interpreted.

So yes, Chrome currently only render XML files (with its optional leading XSL stylesheet declaration), only if it is served as "text/xml", but not as "application/xml" as it should for client-side rendered XML with an XSL declaration.

For XML files served as "text/xml" or "application/xml" and that do not contain an XSL stylesheet declaration, Chrome should still use a default stylesheet to render it as a DOM tree, or at least as its text source. But it does not, and here again it attempts to render it as if it was HTML, and bugs immediately on many scripts (including a default internal one) that attempt to access to "document.body" for handling onLoad events and inject some javascript handler in it.

An example of site that does not work as expected (the Common Lisp documentation) in Chrome, but works in IE which supports client-side XSLT:

http://common-lisp.net/project/bknr/static/lmman/toc.html

This index page above is displayed correctly, but all links will drive to XML documents with a basic XSL declaration to an existing XSL stylesheet document, and you can wait indefinitely, thinking that the chapters have problems to be downloaded. All you can do to read the docuemntation is to open the console and read the source code in the Resources tab.

The other answer below by Eric is wrong. The namespace declaration he mentioned had nothing to do with the problem.

The real reason it doesn't work is due to security concerns (cf. issue 4197, issue 111905).

Imagine this scenario:

  1. You receive an email message from an attacker containing a web page as an attachment, which you download.

  2. You open the now-local web page in your browser.

  3. The local web page creates an <iframe> whose source is https://mail.google.com/mail/.

  4. Because you are logged in to Gmail, the frame loads the messages in your inbox.

  5. The local web page reads the contents of the frame by using JavaScript to access frames[0].document.documentElement.innerHTML. (An online web page would not be able to perform this step because it would come from a non-Gmail origin; the same-origin policy would cause the read to fail.)

  6. The local web page places the contents of your inbox into a <textarea> and submits the data via a form POST to the attacker's web server. Now the attacker has your inbox, which may be useful for spamming or identify theft.

Chrome foils the above scenario by putting restrictions on local files opened using Chrome. To overcome these restrictions, we've got two solutions:

  1. Try running Chrome with the --allow-file-access-from-files flag. I've not tested this myself, but if it works, your system will now also be vulnerable to scenarios of the kind mentioned above.

  2. Upload it to a host, and problem solved.

I had the same problem on localhost. Running around the Internet looking for the answer and I approve that adding --allow-file-access-from-files works. I work on Mac, so for me I had to go through terminal sudo /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --allow-file-access-from-files and enter your password (if you have one).

Another small thing - nothing will work unless you add to your .xml file the reference to your .xsl file as follows <?xml-stylesheet type="text/xsl" href="<path to file>"?>. Another small thing I didn't realise immediately - you should be opening your .xml file in browser, no the .xsl.

I tried putting the file in the wwwroot. So when accessing the page in Chrome, this is the address localhost/yourpage.xml.

What Eric says is correct.

In the xsl, for the xsl:stylesheet tag have the following attributes

version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml"

It works fine in chrome.

I started testing this and ran into the local file / Chrome security issue. A very simple workaround is put the XML and XSL file in, say, Dropbox public folder and get links to both files. Put the link to the XSL transform in the XML head. Use the XML link in Chrome AND IT WORKS!

The problem based on Chrome is not about the xml namespace which is xmlns="http://www.w3.org/1999/xhtml". Without the namesspace attribute, it won't work with IE either.

Because of the security restriction, you have to add the --allow-file-access-from-files flag when you start the chrome. I think linux/*nix users can do that easily via the terminal but for windows users, you have to open the properties of the Chrome shortcut and add it in the target destination as below;

Right-Click -> Properties -> Target

enter image description here

Here is a sample full path with the flags which I use on my machine;

"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --allow-file-access-from-files

I hope showing this step-by-step will help windows users for the problem, this is why I've added this post.

After 8 years the situation is changed a bit.

I'm unable to open a new session of Google Chrome without other parameters and allow 'file:' schema.

On macOS I do:

open -n -a "Google Chrome" --args \
--disable-web-security \               # This disable all CORS and other security checks
--user-data-dir=$HOME/fakeChromeDir    # This let you to force open a new Google Chrome session

Without this arguments I'm unable to test the XSL stylesheet in local.