Chrome createAttribute malforms prefix - javascript

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>

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.

Run exe file from Javascript

How can I run exe file from Mozilla Filrefox?
I tried this but it not working.
var oShell = new ActiveXObject("Shell.Application");
var comandtoRun = "C:\\Buziol Games\\Mario Forever\\Mario Forever.exe";
oShell.ShellExecute(comandtoRun,"","","open","1");
You can't run any system command from a web page. This was only possible with Internet Explorer under certain conditions, but fortunately it's not something you can do with modern browsers.
Perhaps your path isn't right. It could be produced by whitheSpaces.
You can solve it by quoting folder names wich contains whitespaces, like this.
var oShell = new ActiveXObject("Shell.Application");
var comandtoRun = "C:\\'Buziol Games'\\'Mario Forever'\\'Mario Forever.exe'";
oShell.ShellExecute(comandtoRun,"","","open","1");
If ActiveXObject not works on firefox, you can use window.open function.
window.open('file:///C:"Buziol Games"/"Mario Forever"/"Mario Forever.exe"');

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.

Stymied by recent changes in browser javascript DOMParser and XSL

The following used to work on Firefox 3.5.x and 3.6.x but it no longer does in Firefox 11.x or Safari 5.1.x. Javascript isn't my specialty, so I'm not up to speed on recent changes.
Specifically, the Browse button apparently still 'successfully' loads a file (which should be an XML sequence export from FCP although this is not validated), but upon pressing the Process button the results of the XSLT no longer appear in the 'output' DIV as they used to with previous browser versions.
It can be seen in context at http://johnpilgrim.net/color/jProcess.html
An appropriate sample XML file for testing is available at http://johnpilgrim.net/color/sample.xml
Nothing changed in the html, javascript or xsl so it seems to be a change in the recent browsers. I only designed and tested it to work in Firefox, and so never tested it in anything else.
Thoughts? Solutions?
Thanks!
John
<head>
<script type="text/javascript">
function jProcess(){
// Get the file contents locally, using the nifty Firefox 3 nsIDOMFile interface
var file_contents = document.getElementById('xml_file').files.item(0).getAsText("utf8");
// Cast/Convert to an XML Document
var parser = new DOMParser();
xmlDoc = parser.parseFromString(file_contents, "text/xml");
// XSLT Transformation
var xslt = document.implementation.createDocument("", "", null);
xslt.async = false;
xslt.load("jProcess.xsl");
var process = new XSLTProcessor();
process.importStylesheet(xslt);
var result = process.transformToFragment(xmlDoc, document);
// Show the output
document.getElementById('output').innerHTML= " ";
document.getElementById('output').appendChild(result);
return false;
};
</script>
</head>
<body>
<form method="post" onsubmit="return jProcess();">
<fieldset>
<legend>Select the XML file for the FCP sequence you want to process into HTML.</legend>
<input type="file" size=100 name="xml_file" id="xml_file">
<input type="submit" value="Convert">
</fieldset>
</form>
<div id="output"></div>
I tried your sample with Firefox 12 on Windows, the error console shows an error
Timestamp: 01.05.2012 11:23:43
Error: document.getElementById("xml_file").files.item(0).getAsText is not a function
Source File: http://johnpilgrim.net/color/jProcess.html
Line: 40
so the code simply does not work any more due to changes in the API exposed on the input type="file" control respectively the File objects exposed in the FileList exposed by that control. Based on https://developer.mozilla.org/en/DOM/File the method getAsText was obsoleted in Gecko/FF 7 and probably removed later on. To read the contents of a file you are now supposed to use https://developer.mozilla.org/en/DOM/FileReader#readAsText%28%29. That seems to be a further asynchronous API so you will have to restructure your code: http://home.arcor.de/martin.honnen/xml/test2012050101.html (that sample works for me with current version of Firefox, Opera and Chrome).
So an example using FileReader looks like
function transform(file, sheetUrl) {
if (typeof FileReader !== 'undefined') {
var fileReader = new FileReader();
fileReader.onload = function(evt) {
var doc = new DOMParser().parseFromString(this.result, 'application/xml');
var proc = new XSLTProcessor();
var req = new XMLHttpRequest();
req.open('GET', sheetUrl, false);
req.send(null);
proc.importStylesheet(req.responseXML);
document.body.appendChild(proc.transformToFragment(doc, document));
};
fileReader.readAsText(file);
}
else {
console.log('No FileReader support.');
}
}

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

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

Categories