Sign in to follow this  
Erzengeldeslichtes

[web] XSL kills Javascript external scripts?

Recommended Posts

I'm having trouble with XSL and javascript (using IE6). I have some external scripts which include objects and functions. I have an XSL that needs to use these scripts. I try to include the scripts but it simply won't work. Here's a sample I built and have tested, ensuring it shows the same error.
//test.js
function TestObject(Name, Foo)
{
 this.name = Name;
 this.foo = Foo;
}
//test.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:template match="/">
  <html>
   <head>
    <script language="javascript" src="test.js"></script>
    <script language="javascript" type="text/javascript">
    Test = new Array;
    Test.push(new TestObject("Test", "Test"));
    </script>
   </head>
   <body>
    <script type="text/javascript">
    for(i=0; i&lt;Test.length; ++i)
    {
     document.write(Test[i].name);
    }
    </script>
   </body>
  </html>
 </xsl:template>
</xsl:stylesheet>

As it stands, it complains "TestObject is undefined". Now if I, by hand, make this into an html file:
<html>
 <head>
  <script language="javascript" src="test.js"></script>
  <script language="javascript" type="text/javascript">
  Test = new Array;
  Test.push(new TestObject("Test", "Test"));
  </script>
 </head>
 <body>
  <script type="text/javascript">
  for(i=0; i<Test.length; ++i)
  {
   document.write(Test[i].name);
  }
  </script>
 </body>
</html>

It works perfectly fine, no complaints. If I don't use the external file:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:template match="/">
  <html>
   <head>
    <script language="javascript" type="text/javascript">
    function TestObject(Name, Foo)
    {
     this.name = Name;
     this.foo = Foo;
    }
    Test = new Array;
    Test.push(new TestObject("Test", "Test"));
    </script>
   </head>
   <body>
    <script type="text/javascript">
    for(i=0; i&lt;Test.length; ++i)
    {
     document.write(Test[i].name);
    }
    </script>
   </body>
  </html>
 </xsl:template>
</xsl:stylesheet>

it also works fine. Unfortunately, turning into an HTML by hand defeats the purpose of an XML file (which isn't used in this example, even though it's provided. It is used where I actually need it). As well, moving the objects into the XSL files themselves defeats the purpose of an external JS file. Why can't I use both? How can I get around it?

Share this post


Link to post
Share on other sites
1.) Do you have the same problem if you try using HTML files instead of XSL files?
2.) What about using xsl:script? This probably is not what you're going for, but just asking.

Share this post


Link to post
Share on other sites
Have a look at the output XML (HTML), and then try pasting that into a html file to see if the same thing happens (in IE).

I'm pretty sure there's a bug in IE's HTML parser which causes it to misinterpret


<script src="something" type="text/javascript" />


as

<script src="something" type="text/javascript">


Which is of course, should be completely different.

Basically, if you use a self-closing XML tag for script in IE, you're in trouble (i.e. it will break the entire page).

Perhaps that's what your XSLT has done - if so, you need to make it so it won't do so.

Mark

Share this post


Link to post
Share on other sites
Hrm. This is strange, too. When I use "<?xml-stylesheet type="text/xsl" href="test.xsl"?>" in the XML file, it works. When I use test.htm, it doesn't.

Test.htm:

<html>
<body>
<script type="text/javascript">
XMLFile = "test.xml"
XSLFile = "test.xsl"
ToCall = document.write
//Borrowed from W3Schools.org
/* xml = new ActiveXObject("Microsoft.XMLDOM");
xml.async = false;
xml.load(XMLFile);
xsl = new ActiveXObject("Microsoft.XMLDOM");
xsl.async = false;
xsl.load(XSLFile);
ToCall(xml.transformNode(xsl));
/*/

//Borrowed from "Using XML Technologies For Enhancing Log Files"
function onViewLog( )
{

var moz = (typeof document.implementation != 'undefined') &&
(typeof document.implementation.createDocument != 'undefined');
if (moz)
{
onViewLog_Mozilla();
}
else
{
onViewLog_IE();
}

}
function onViewLog_IE()
{

xmlDoc = new ActiveXObject( "MSXML2.DOMDocument.[[3]].[[0]]" );
xslDoc = new ActiveXObject( "MSXML2.FreeThreadedDOMDocument.[[3]].[[0]]" );
var xslTemplate = new ActiveXObject( "MSXML2.XSLTemplate.[[3]].[[0]]" );

//[[1]]. Load in the raw XML data:
xmlDoc.async = "false";
xmlDoc.load( XMLFile );

//[[2]]. Load in the XSLT transform script:
xslDoc.async = "false";
xslDoc.load( XSLFile );

xslTemplate.stylesheet = xslDoc;
xslProcessor = xslTemplate.createProcessor( );
xslProcessor.input = xmlDoc;

//[[3]]. Overwrite the xsl:params with runtime selected values:
// xslProcessor.addParameter( "eventType", g_eventType );

//[[4]]. Output the XML (as processed by the XSLT) to the div target
xslProcessor.transform();
ToCall(xslProcessor.output);

}function onViewLog_Mozilla()
{

//[[1]]. Load in the raw XML data:
xmlDoc = document.implementation.createDocument("", "", null);
xmlDoc.load( XMLFile );
xmlDoc.onload = readXML;

}

function readXML()
{

xslDoc = document.implementation.createDocument("", "test", null);
xslProcessor = new XSLTProcessor();

//[[2]]. Load in the XSLT transform script:
xslDoc.addEventListener("load", xslLoad, false);
xslDoc.load( XSLFile );

}

function xslLoad()
{

xslProcessor.importStylesheet( xslDoc );

//[[3]]. Overwrite the xsl:params with runtime selected values:
// xslProcessor.setParameter( "", "eventType", g_eventType );

//[[4]]. Output the XML (as processed by the XSLT) to the div target
xmlOutput = xslProcessor.transformToDocument( xmlDoc );
var xmlSerializer = new XMLSerializer();
ToCall(xmlSerializer.serializeToString( xmlOutput ));

}

onViewLog();//*/

</script>
</body>
</html>





And it's yet another "I really can't do without this." I've tried both the commented out section and the currently used section, both result in the same error.

If I change ToCall to be:

ToCall = function(OUTPUT)
{
document.write(OUTPUT.replace(new RegExp("<", "g"), "<"));
}

then copy & past the resulting text into a new HTML file, it works fine, just like if I do it by hand. So why doesn't it work with the code posted above?

[Edited by - Erzengeldeslichtes on July 11, 2005 11:08:08 AM]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this