mozilla client side XSLT not displaying. (Using jQuery too) - javascript

I want to use firebug to debug and help be quickly finish some XSLT layout issues, but I cannot get the following code to perform and display the client side XSLT in Firefox (everything is fine in IE):
$().ready(function() {
var oXMLHTTP
var oXSLT
if ($.browser.mozilla){
oXMLHTTP = document.implementation.createDocument("","",null);
oXSLT = document.implementation.createDocument("","",null);
}else{
oXMLHTTP = new ActiveXObject("Microsoft.XMLDOM");
oXSLT = new ActiveXObject("Microsoft.XMLDOM");
}
oXMLHTTP.async = false;
oXSLT.async = false;
oXSLT.load('Layout.xslt');
var sURL = "somepage"
/**/
$.get(sURL,function(data){
var sTranformedXML = "";
if ($.browser.mozilla){
oXMLHTTP.load(data);
var xsltProcessor = new XSLTProcessor();
xsltProcessor.importStylesheet(oXSLT);
var mDoc = document.implementation.createDocument("","",null);
sTranformedXML = xsltProcessor.transformToFragment(oXMLHTTP,mDoc);
}else{
oXMLHTTP.loadXML(data);
sTranformedXML = oXMLHTTP.transformNode(oXSLT)
}
$("#main").html(sTranformedXML);
$("#tbl_Not Grouped").insertAfter("tbl_Social Sciences");
})// $.get
})
Is there something that I have overlooked here?
I really only need the Firefox code testing. So, it does not need to be pretty.

Gecko's XSL-T implementation is known to handle default namespaces wrongly. Try prefixing elements in your XML document and/or prefix elements in XPath queries in XSL document (do not forget to bind new prefixes)

This does not really answer your question per se, but you might consider taking a look at Google AJAXSLT, which wraps the various browsers' capabilities and "fills in the gaps:" link

Related

XML transformation error. Working in IE8 but not an other browser. xmlDOM transformNode breaking newer browsers

I am having browser issues running the following scripts. It's a very old application I inherited and I can find no references to this issue that is not more than 5, 7 and 10 years ago.
The script works only when running IE in IE7 compatibility mode, and does not work in any other browser.
gei("calUTA").innerHTML = "<td><xml id=\"calXSLUTA\"><xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\"><xsl:template match=\"/\"><xsl:for-each select=\"/root/month\"><xsl:if test=\"name=\'"+moName[showMo]+"\' and year=\'"+showYr+"\'\"><xsl:value-of select=\"uta\"/></xsl:if></xsl:for-each></xsl:template></xsl:stylesheet></xml></td>";
loopTrans("calXSLUTA","calUTA","big");
function loopTrans(f1,f2,z)
{ if (z == "big" || z == "stu") {
xmlDOM = gei(z + "XML").XMLDocument;
}
xslDOM = eval(f1 + ".XMLDocument");
gei(f2).innerHTML = xmlDOM.transformNode(xslDOM);
}
Newer browsers appear to be erroring out while executing the transformNode function. Any help will be appreciated.
The specific error message returned is "Unable to get property 'transformNode' of undefined or null reference".
The API to run client-side XSLT 1.0 by the browser from JavaScript in any other browsers but IE based ones is documented at https://developer.mozilla.org/en-US/docs/Web/API/XSLTProcessor. The whole IE legacy stuff like XML data islands is not even supported in the last IE versions, although they should still allow you to instantiate new ActiveXObject('Msxml2.DOMDocument.3.0') to have an XML DOM document to loadXML the XML input or the XSLT code from a string (or the load method to load from a URL) and then run transformNode on that created XML DOM.
So IE code would be like
var xmlDoc = new ActiveXObject('Msxml2.DOMDocument.3.0');
xmlDoc.loadXML('<root><month>..<\/month><\/root>');
var xsltDoc = new ActiveXObject('Msxml2.DOMDocument.3.0');
xsltDoc.loadXML('<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\"><xsl:template match=\"/\"><xsl:for-each select=\"/root/month\"><xsl:if test=\"name=\'"+moName[showMo]+"\' and year=\'"+showYr+"\'\"><xsl:value-of select=\"uta\"/></xsl:if></xsl:for-each></xsl:template></xsl:stylesheet>');
var transformationResult = xmlDoc.transformNode(xsltDoc); // assign the result string to innerHTML of an HTML element to render it
other browser like
var domParser = new DOMParser();
var xmlDoc = domParser.parseFromString('<root><month>..<\/month><\/root>', 'application/xml');
var xsltDoc = domParser.parseFromString('<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\"><xsl:template match=\"/\"><xsl:for-each select=\"/root/month\"><xsl:if test=\"name=\'"+moName[showMo]+"\' and year=\'"+showYr+"\'\"><xsl:value-of select=\"uta\"/></xsl:if></xsl:for-each></xsl:template></xsl:stylesheet>', 'application/xml');
var xsltProcessor = new XSLTProcessor();
xsltProcessor.importStylesheet(xsltDoc);
var transformationResult = xsltProcessor.transformToFragment(xmlDoc, document); // insert this document fragment with e.g. appendChild to HTML element to render it
In any case, if you don't need IE support, I would consider ditching XSLT 1 and using Saxon-JS 2 and XSLT 3 instead. In any case, the use of an XSLT parameter with xsl:param instead of that string concatenation in <xsl:if test=\"name=\'"+moName[showMo]+"\' should make the code more robust.

Chrome createAttribute malforms prefix

I've got a simple piece of javascript that adds an exslt namespace to an xsl document. However, Chrome and Firefox handle this differently. Firefox will add the namespace correctly to the root with the full
xmlns:exsl="http://exslt.org/common"
Chrome however just plunks in
exsl="http://exslt.org/common"
Did you see the difference? 'xmlns' is gone in the latter and Chrome itself thinks the xslt is malformed: it returns null when you transform! If you correctly prefix, i.e., xmlns:exsl and then Chrome likes it. Try the fiddle below with Firefox and then with Chrome to see the difference. Here is the simple code
var styleString = '<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:template match="/"><div>hi</div></xsl:template></xsl:stylesheet>';
var xslDoc = (new DOMParser()).parseFromString(styleString, "text/xml");
var docRoot = xslDoc.documentElement;
a = document.createAttribute("xmlns:exsl");
a.nodeValue = "http://exslt.org/common";
docRoot.setAttributeNode(a);
var xmls1 = new XMLSerializer();
var outputXHtmlString = xmls1.serializeToString(xslDoc);
document.getElementById("content").innerText = outputXHtmlString;
Use this
var styleString = '<xsl:stylesheet version="1.0" xmlns:xsl="w3.org/1999/XSL/Transform" xmlns:exsl="exslt.org/common"><xsl:template match="/"><div>hi</div></xsl:template></xsl:stylesheet>

How do I use jQuery in Windows Script Host?

I'm working on some code that needs to parse numerous files that contain fragments of HTML. It seems that jQuery would be very useful for this, but when I try to load jQuery into something like WScript or CScript, it throws an error because of jQuery's many references to the window object.
What practical way is there to use jQuery in code that runs without a browser?
Update: In response to the comments, I have successfully written JavaScript code to read the contents of files using new ActiveXObject('Scripting.FileSystemObject');. I know that ActiveX is evil, but this is just an internal project to get some data out of some files that contain HTML fragments and into a proper database.
Another Update: My code so far looks about like this:
var fileIo, here;
fileIo = new ActiveXObject('Scripting.FileSystemObject');
here = unescape(fileIo.GetParentFolderName(WScript.ScriptFullName) + "\\");
(function() {
var files, thisFile, thisFileName, thisFileText;
for (files = new Enumerator(fileIo.GetFolder(here).files); !files.atEnd(); files.moveNext()) {
thisFileName = files.item().Name;
thisFile = fileIo.OpenTextFile(here + thisFileName);
thisFileText = thisFile.ReadAll();
// I want to do something like this:
s = $(thisFileText).find('input#txtFoo').val();
}
})();
Update: I posted this question on the jQuery forums as well: http://forum.jquery.com/topic/how-to-use-jquery-without-a-browser#14737000003719577
Following along with your code, you could create an instance of IE using Windows Script Host, load your html file in to the instance, append jQuery dynamically to the loaded page, then script from that.
This works in IE8 with XP, but I'm aware of some security issues in Windows 7/IE9. IF you run into problems you could try lowering your security settings.
var fileIo, here, ie;
fileIo = new ActiveXObject('Scripting.FileSystemObject');
here = unescape(fileIo.GetParentFolderName(WScript.ScriptFullName) + "\\");
ie = new ActiveXObject("InternetExplorer.Application");
ie.visible = true
function loadDoc(src) {
var head, script;
ie.Navigate(src);
while(ie.busy){
WScript.sleep(100);
}
head = ie.document.getElementsByTagName("head")[0];
script = ie.document.createElement('script');
script.src = "http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js";
head.appendChild(script);
return ie.document.parentWindow;
}
(function() {
var files, thisFile, win;
for (files = new Enumerator(fileIo.GetFolder(here).files); !files.atEnd(); files.moveNext()) {
thisFile = files.item();
if(fileIo.GetExtensionName(thisFile)=="htm") {
win = loadDoc(thisFile);
// your jQuery reference = win.$
WScript.echo(thisFile + ": " + win.$('input#txtFoo').val());
}
}
})();
This is pretty easy to do in Node.js with the cheerio package. You can read in arbitrary HTML from whatever source you want, parse it with cheerio and then access the parsed elements using jQuery style selectors.

How can I get the XUL as a string from a Mozilla add-on at run-time using JavaScript?

I'm trying to get a window's XUL text as a String in Javascript. I need it to be done at runtime because the window adds/removes UI elements dynamically.
I have tried the following:
document.toXML()
document.xml
document.documentElement.toXML()
Among other things. Nothing works! Can anyone help?
You use XMLSerializer:
new XMLSerializer().serializeToString(document);
I don't think there is a function or field to get xul text, but you can work around by reading the content from xul url
function getContentFromURL(url) {
var Cc = Components.classes;
var Ci = Components.interfaces;
var ioService = Cc['#mozilla.org/network/io-service;1'].getService(Ci.nsIIOService);
var scriptableStream = Cc['#mozilla.org/scriptableinputstream;1'].getService(Ci.nsIScriptableInputStream);
var channel = ioService.newChannel(url, null, null);
var input = channel.open();
scriptableStream.init(input);
return scriptableStream.read(input.available());
}
so you can call getContentFromURL(document.location) to get the XUL content

Javascript XML reading problem

I'm having problems reading an XML local input. The weird thing is that this code works perfectly when the XML is located on a server(This is desktop, by the way, so no SOP problems). I can't figure this out for the life of me, and I've been staring at it, trying different things for a couple of hours.
And another question: does the XML document need a css sheet to be properly read? I would imagine that it doesn't, but I don't know too much about it.
function verify()
{
zipObj = new ActiveXObject("Msxml2.XMLHTTP");
zipObj.open("GET", "KMSY.xml", false);
zipObj.onreadystatechange = function() {
if (zipObj.readyState === 4) {
zipXML = zipObj.responseXML;
read(zipXML);
}
else {
document.getElementById("notice").innerHTML = zipObj.readyState;
}
}
zipObj.send();
}
function read(zipXML)
{
var temp = zipXML.getElementsByTagName("temp_f")[0].childNodes[0].nodeValue;
document.getElementById("notice").innerHTML = temp;
}
Import the XML file to a local server, AJAX obviously needs the XML files to be on web server in order to parse them, or so my humble experience tells me.
You might also want to add the compatibility code for other XML requests into your code.
new XMLHttpRequest() for all browser and IE 8+
new ActiveXObject("Microsoft.XMLHTTP") IE prior to 8

Categories