XSL not working in Google Chrome
Asked Answered
P

6

21

I've seen plenty of posts all around about this... but I can not, for the life of me, figure out what my problem is! Google Chrome just displays a blank page when I try to transform XML with XSL. When I view source, I see the raw XML. IE works.

I have an XML document that looks like this...

<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="http://localhost/xsl/listXSL.php"?>
<links>
  <link id="1" name="Google Home Page" url="http://www.google.com/" clicks="0" />
  <link id="2" name="Facebook" url="http://www.facebook.com/" clicks="1" />
  <link id="3" name="Gmail" url="http://gmail.com" clicks="2" />
</links>

... and then the linked XSL file which looks like this...

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <xsl:for-each select="links/link">
    <a>
        <xsl:attribute name="href">
            <xsl:value-of select="@url" />
        </xsl:attribute>
        <xsl:value-of select="@name" />
    </a><br />
  </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

You might notice that the XSL file is actually a PHP file, but this works fine in other browsers and I've tried changing it to .xsl for Chrome, but it doesn't help. What I'm doing wrong here?

Pasteurize answered 29/12, 2010 at 21:48 Comment(1)
You may want to see: #2982024Jsandye
H
19

The reason this doesn't work is due to a security concern that Chrome has addressed in a controversial way[1][2][3][4], by blocking XML files from accessing local XSLT files in the same directory, while HTML files can access .CSS files in the same directory just fine.

The justification given by the Chrome team in 2008 was this:


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 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 Internet 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 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.

There is nothing Gmail can do to defend itself from this attack.


I do agree it's annoying, as a fix you've got 2 solutions:

  1. Try running chrome with the --allow-file-access-from-files switch (I've not tested this myself)

  2. Upload it to a host, and everything will be fine.

Hepato answered 6/6, 2011 at 12:12 Comment(4)
--allow-file-access-from-files seems to have no effect in this situation.Jameyjami
Nope. -allow-file-access-from-files works perfectly fine, but be sure that chrome is closed before running that switch. (And of course, your XSLT cannot have any mistakes).Intercessor
Chrome's decision is silly. While their security concern makes sense, XML files should be able to load XSL stylesheets from the same directory, just as HTML files can load images, stylesheets, and scripts from the same directory. There's an issue you can star but the Chrome dev team has banned new comments on it - despite the fact that they complained they can't quantify how badly users wanted the local file origin to be relaxed.Jocasta
Maybe it's time to rethink about this? I don't think that scenario is possible anymore. Loading gmail in a frame fails with Refused to display in a frame because it set 'X-Frame-Options' to 'sameorigin'. error. That's even answered in SO: https://mcmap.net/q/219329/-how-can-i-lt-iframe-gt-gmail. So, since one can refuse one's content to load in a frame whether the page is local or not maybe it's time for Chrome to do XSLT some justice?Nikola
L
5

Uploading to host soves problem for me. --allow-file-access-from-files switch solution did not work for me.

Lymphoblast answered 23/12, 2011 at 18:20 Comment(0)
M
2

In older version of Chrome, if you don't output a proper document with a known vocabulary (HTML, XHTML, SVG, etc.) you will not get a rendered page.

In modern version (I have 10.0.612.3 dev installed), you get an styleless XML document (with a parsing error in your case because of the more than one root element result).

Solution: Output a proper (with all the mandatory elements) HTML 4.0 document, or a proper (also with correct namespace) XHTML 1.0 document.

Mccutchen answered 29/12, 2010 at 23:29 Comment(0)
B
1

Using --allow-file-access-from-files switch does the trick for me.

I was trying to use offline documentation from installed software on my system. IE showed content by only asking permission to enable contents. I would say this can be added to chrome as well without sacrificing security.

Baseboard answered 24/5, 2017 at 15:49 Comment(0)
T
0

I was able to load xml contents into html in chrome by storing the xml as variable in javascript as shown below.

<html>
<head>testing</head>

<body>
<span id="num"></span> <span id="street"></span><br /> <span id="city"></span>, <span id="state"></span> <span id="zip"></span>

<script>
txt="<address>"+
 "<street>Roble Ave</street>"+
  "<mtfcc>S1400</mtfcc>"+
  "<streetNumber>649</streetNumber>"+
  "<lat>37.45127</lat>"+
  "<lng>-122.18032</lng>"+
  "<distance>0.04</distance>"+
  "<postalcode>94025</postalcode>"+
  "<placename>Menlo Park</placename>"+
  "<adminCode2>081</adminCode2>"+
  "<adminName2>San Mateo</adminName2>"+
  "<adminCode1>CA</adminCode1>"+
  "<adminName1>California</adminName1>"+
  "<countryCode>US</countryCode>"+
 "</address>";

if (window.DOMParser)
  {
  parser=new DOMParser();
  xmlDoc=parser.parseFromString(txt,"text/xml");
  }
else // Internet Explorer
  {
  xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
  xmlDoc.async=false;
  xmlDoc.loadXML(txt);
  }
document.getElementById("num").innerHTML=
xmlDoc.getElementsByTagName("streetNumber")[0].childNodes[0].nodeValue;
document.getElementById("street").innerHTML=
xmlDoc.getElementsByTagName("street")[0].childNodes[0].nodeValue;
document.getElementById("city").innerHTML=
xmlDoc.getElementsByTagName("adminName2")[0].childNodes[0].nodeValue;
document.getElementById("state").innerHTML=
xmlDoc.getElementsByTagName("adminCode1")[0].childNodes[0].nodeValue;
document.getElementById("zip").innerHTML=
xmlDoc.getElementsByTagName("postalcode")[0].childNodes[0].nodeValue;
</script>
</body>
</html>

screenshot this answer helped me

Tether answered 4/8, 2017 at 18:59 Comment(0)
P
0

And here you go! It's actually very easy to use. Were you trying to use it on <body></body> tags? That doesn't work. It has to be a child of the body tag.

var xsltProcessor = new XSLTProcessor();
var myXMLHTTPRequest = new XMLHttpRequest();
myXMLHTTPRequest.open("GET", "chatxml.xsl", false);
myXMLHTTPRequest.send(null);

xslStylesheet = myXMLHTTPRequest.responseXML;
xsltProcessor.importStylesheet(xslStylesheet);


// load the xml file, example1.xml
myXMLHTTPRequest = new XMLHttpRequest();
myXMLHTTPRequest.open("GET", "44f683a84163b3523afe57c2e008bc8c.xml", false);
myXMLHTTPRequest.send(null);
xmlDoc = myXMLHTTPRequest.responseXML;

var fragment = xsltProcessor.transformToFragment(xmlDoc, document);

document.innerHTML = fragment;
console.log();
document.getElementById("c").appendChild(fragment);
Purl answered 13/1, 2020 at 5:14 Comment(1)
This isn't a complete solution. There's definitely some assembly still required before this will work (besides changing the file names)Epanorthosis

© 2022 - 2024 — McMap. All rights reserved.