Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations biv343 on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

XSL Transform and Netscape/Mozilla

Status
Not open for further replies.

firsttube

Technical User
Apr 21, 2004
165
CA
Does XSL transform work in Netscape and Mozilla? I have a file that works in IE, but not the other two.

Set the gearshift for the high gear of your soul, you've got to run like an antelope, out of control.
 
Yes, should do. Whats the code and how you transforming it?
 
here's the code (it's inside javascript)
Code:
var xslt = new ActiveXObject("Msxml2.DOMDocument");
				xslt.async = false;
				xslt.loadXML("<?xml version='1.0'?>\n" +
					"<xsl:stylesheet xmlns:xsl='[URL unfurl="true"]http://www.w3.org/1999/XSL/Transform'[/URL] version='1.0'>\n" +
					"  <xsl:template match='/data/item'>\n" +
					"    <table><xsl:apply-templates select='cell'/></table>\n" +
					"  </xsl:template>\n" +
					"  <xsl:template match='cell'>\n" +
					"      <tr><td bgcolor='#4e80b4'><xsl:value-of select='@name'/></td><td bgcolor='#4e80b4'><xsl:value-of select='@value'/></td></tr>\n" +
					"  </xsl:template>\n" +
					"</xsl:stylesheet>");
				dataTable.innerHTML = data.transformNode(xslt);

And the xml looks like this:
Code:
<data>
	<item>
		<cell name="ID" value="159352" />
		<cell name="PIN" value="123455" />
		<cell name="test" value="test" />
	</item>
</data>

and then this is where the transformed xml is supposed to be injected:
Code:
<xml id="data">
				<%= xml%>
			</xml>
			<div id="dataTable" style="align: left; width: 200px"></div>

Set the gearshift for the high gear of your soul, you've got to run like an antelope, out of control.
 
Wow, this was so much harder than I thought it would be and I only have a workaround that ought to be better. I've learnt a lot answering this question.

Points:

1. Stylesheet is incorrect. Should be "data/item" not "/data/item" or it will only match the cells.

2. Mozilla does not use Active X objects. To create a DOM document, you have to use document.implementation.createDocument("", "test", null) instead. This means you need to put a check in to see which methods the browser can use (determine whether its mozilla or IE basically), then act accordingly.

3. If you what to develop cross-browser solutions, you should use standards compliant HTML (with appropriate DOCTYPE) and CSS. XML data islands are not standards compliant (why not use a seperate XML file and load it in?).

4. dataTable is an IE only way of referencing the node. Standards compliant is document.getElementById("dataTable").

5. innerHTML is non-standard. I tried to find a way around using it, by using appendChild, but I couldn't get it to work (if someone can show me that would be great).

6. There's probably a better way of achieving what you want.

Very interesting problem though. This is what I came up with:

Code:
  var stylesheet = "<?xml version='1.0'?>\n" +
    "<xsl:stylesheet xmlns:xsl='[URL unfurl="true"]http://www.w3.org/1999/XSL/Transform'[/URL] version='1.0'>\n" +
    "  <xsl:template match='data/item'>\n" +
    "    <table><xsl:apply-templates select='cell'/></table>\n" +
    "  </xsl:template>\n" +
    "  <xsl:template match='cell'>\n" +
    "      <tr style='background-color: #4e80b4'><td><xsl:value-of select='@name'/></td><td><xsl:value-of select='@value'/></td></tr>\n" +
    "  </xsl:template>\n" +
    "</xsl:stylesheet>";
  if (document.implementation && document.implementation.createDocument)
  {
    var objDOMParser = new DOMParser();
    var xslt = objDOMParser.parseFromString(stylesheet, "text/xml")
    var processor = new XSLTProcessor();
    processor.importStylesheet(xslt);
    var data = document.getElementById("data");
    var result = processor.transformToDocument(data);
    var xmls = new XMLSerializer();
    var output = xmls.serializeToString(result);
    document.getElementById("dataTable").innerHTML = "<table>" + output + "</table>";
  }
  else if (window.ActiveXObject)
  {
    xslt = new ActiveXObject("Microsoft.XMLDOM");
    xslt.async = false;
    xslt.loadXML(stylesheet);
    document.getElementById("dataTable").innerHTML = document.getElementById("data").transformNode(xslt);
  }
  else
  {
    alert('Your browser can\'t handle this script');
  }
Also, the parser doesn't recognise self-closed tags, so your xml will need to be:
Code:
<xml id="data">
  <data>
    <item>
      <cell name="ID" value="159352"></cell>
      <cell name="PIN" value="123455"></cell>
      <cell name="test" value="test"></cell>
    </item>
  </data>
</xml>
 
Wow, JontyMC, thank you so much for your help! Your suggestion works in IE, but in NS and Mozilla, it only displays the first line:
Code:
<cell name="ID" value="159352"></cell>

Unfortunately I cannot avoid the self-closing tags, because the XML is coming in as a stream from another application -- which I cannot change. Is that maybe why it only displays the first one?

thanks again!
ft


Set the gearshift for the high gear of your soul, you've got to run like an antelope, out of control.
 
Yes, the way the parser works in mozilla, it will read it as (I think):
Code:
<xml id="data">
  <data>
    <item>
      <cell name="ID" value="159352">
        <cell name="PIN" value="123455">
          <cell name="test" value="test"></cell>
        </cell>
      </cell>
    </item>
  </data>
</xml>
So you could allow for that by making a slight change to the stylesheet:
Code:
  var stylesheet = "<?xml version='1.0'?>\n" +
    "<xsl:stylesheet xmlns:xsl='[URL unfurl="true"]http://www.w3.org/1999/XSL/Transform'[/URL] version='1.0'>\n" +
    "  <xsl:template match='data/item'>\n" +
    "    <table><xsl:apply-templates select='cell'/></table>\n" +
    "  </xsl:template>\n" +
    "  <xsl:template match='cell'>\n" +
    "      <tr style='background-color: #4e80b4'><td><xsl:value-of select='@name'/></td><td><xsl:value-of select='@value'/></td></tr>\n" +
    "    <xsl:apply-templates select="cell"/>\n" +
    "  </xsl:template>\n" +
    "</xsl:stylesheet>";
  if (document.implementation && document.implementation.createDocument)
  {
    var objDOMParser = new DOMParser();
    var xslt = objDOMParser.parseFromString(stylesheet, "text/xml")
    var processor = new XSLTProcessor();
    processor.importStylesheet(xslt);
    var data = document.getElementById("data");
    var result = processor.transformToDocument(data);
    var xmls = new XMLSerializer();
    var output = xmls.serializeToString(result);
    document.getElementById("dataTable").innerHTML = "<table>" + output + "</table>";
  }
  else if (window.ActiveXObject)
  {
    xslt = new ActiveXObject("Microsoft.XMLDOM");
    xslt.async = false;
    xslt.loadXML(stylesheet);
    document.getElementById("dataTable").innerHTML = document.getElementById("data").transformNode(xslt);
  }
  else
  {
    alert('Your browser can\'t handle this script');
  }

Also, I don't think you need the <table> tag around the output (although not sure about this):
Code:
document.getElementById("dataTable").innerHTML = "<table>" + output + "</table>";
At work at the moment, and haven't got firefox (and not allowed to download it!) so can't test.

Jon
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top