How can I use JavaScript to convert XML and XSLT?

I want to use JavaScript to display my XSLT, but nothing is displayed in my browser on my server.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script> <script type="text/javascript" src="main.js"></script> <meta http-equiv="Content-Language" content="en-us"/> <title>Contracting, Licensing and Compliance News</title> </head> <body> <script language="javascript"> function displayMessage() { // Load XML var xml = new ActiveXObject("Microsoft.XMLDOM") xml.async = false xml.load("site-index.xml") // Load the XSL var xsl = new ActiveXObject("Microsoft.XMLDOM") xsl.async = false xsl.load("site-index.xsl") // Transform document.write(xml.transformNode(xsl)) } </script> </body> </html> 
+7
source share
4 answers

The browser can perform the conversion for you. Javascript is not needed, just bind .xsl with .xml as follows:

 <?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="site-index.xsl" ?> 

and just do xml, no html. Assuming your .xsl contains the correct code, along the lines

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" version="4.01" indent="yes"/> <xsl:output doctype-system="http://www.w3.org/TR/html4/strict.dtd"/> <xsl:output doctype-public="-//W3C//DTD HTML 4.01//EN"/> 
+5
source

You should probably let the browser do the conversion using the outlines of the Xenan method. However, this is entirely possible in JavaScript. Here is a brief description of how you can accomplish this in a cross browser.

First you will need to download XML and XSL. There are many ways to do this. As a rule, it will include some kind of AJAX, but not necessarily. To keep this answer simple, I’ll assume that this part is covered, but please let me know if you need more help, and I will edit to include an XML loading example.

Therefore, suppose we have these objects:

 var xml, xsl; 

Where xml contains the XML structure and xsl contains the stylesheet that you want to convert using.


Edit:

If you need to load these objects, you end up using some kind of AJAX form for this. There are many examples of cross-browser AJAX. You would be better off using the library to accomplish this, instead of rolling your own solution. I suggest you take a peek at jquery or YUI, both of which do a great job of this.

However, the basic idea is quite simple. To complete this answer, here is some kind of non-library code that runs this cross browser:

 function loadXML(path, callback) { var request; // Create a request object. Try Mozilla / Safari method first. if (window.XMLHttpRequest) { request = new XMLHttpRequest(); // If that doesn't work, try IE methods. } else if (window.ActiveXObject) { try { request = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e1) { try { request = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e2) { } } } // If we couldn't make one, abort. if (!request) { window.alert("No ajax support."); return false; } // Upon completion of the request, execute the callback. request.onreadystatechange = function () { if (request.readyState === 4) { if (request.status === 200) { callback(request.responseXML); } else { window.alert("Could not load " + path); } } }; request.open("GET", path); request.send(); } 

You should use this code, giving it the path to your XML, and the function that executes when the download completes:

 loadXML('/path/to/your/xml.xml', function (xml) { // xml contains the desired xml document. // do something useful with it! }); 

I updated my example to show this technique. You can find a working demo code here.


To perform the conversion, you will receive a third XML document that is the result of this conversion. If you work with IE, you use the transformNodeToObject "method, and if you work with other browsers, you use" transformToDocument ":

 var result; // IE method if (window.ActiveXObject) { result = new ActiveXObject("MSXML2.DOMDocument"); xml.transformNodeToObject(xsl, result); // Other browsers } else { result = new XSLTProcessor(); result.importStylesheet(xsl); result = result.transformToDocument(xml); } 

At this point, result should contain the resulting transformation. This is still an XML document, and you should consider it as such. If you need a string that you can pass in document.write or innerHTML , you need to do some more work.

Once again, there is an IE method for this and a method that applies to other browsers.

 var x, ser, s = ''; // IE method. if (result.childNodes[0] && result.childNodes[0].xml) { for (x = 0; x < result.childNodes.length; x += 1) { s += result.childNodes[x].xml; } // Other browsers } else { ser = new XMLSerializer(); for (x = 0; x < result.childNodes.length; x += 1) { s += ser.serializeToString(result.childNodes[x]); } } 

Now s should contain the received XML as a string. You should pass this to document.write or innerHTML and do something useful. Please note that it may contain an XML declaration that you might want to remove or not.

I tested this in Chrome, IE9 and FF4. You can find a simplified, barebones, working example of this in my test bench .

Good luck and happy coding!

+29
source

Use this script to convert test.xml with test.xsl and add the output to the container.

  <div id="container"></div> <script> function loadXMLDoc(filename) { if (window.ActiveXObject) { xhttp = new ActiveXObject("Msxml2.XMLHTTP"); } else { xhttp = new XMLHttpRequest(); } xhttp.open("GET", filename, false); xhttp.send(""); return xhttp.responseXML; } xml = loadXMLDoc("test.xml"); xsl = loadXMLDoc("test.xsl"); if (document.implementation && document.implementation.createDocument) { xsltProcessor = new XSLTProcessor(); xsltProcessor.importStylesheet(xsl); resultDocument = xsltProcessor.transformToFragment(xml, document); document.getElementById('container').appendChild(resultDocument); } </script> 
+3
source

This works in Chrome / Firefox / Edge / IE11

  function loadXMLDoc(filename) { if (window.ActiveXObject || "ActiveXObject" in window) { xhttp = new ActiveXObject("Msxml2.XMLHTTP"); } else { xhttp = new XMLHttpRequest(); } xhttp.open("GET", filename, false); xhttp.send(""); return xhttp.responseXML; } if (window.ActiveXObject || "ActiveXObject" in window) { ie(); } else { xml = loadXMLDoc("input.xml"); xsl = loadXMLDoc("mmlctop2_0.xsl"); if (document.implementation && document.implementation.createDocument) { xsltProcessor = new XSLTProcessor(); xsltProcessor.importStylesheet(xsl); resultDocument = xsltProcessor.transformToDocument(xml, document); var serializer = new XMLSerializer(); var transformed = serializer.serializeToString(resultDocument.documentElement); alert(transformed); } } // https://msdn.microsoft.com/en-us/library/ms753809(v=vs.85).aspx function ie() { var xslt = new ActiveXObject("Msxml2.XSLTemplate.3.0"); var xslDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument.3.0"); var xslProc; xslDoc.async = false; xslDoc.load("mmlctop2_0.xsl"); if (xslDoc.parseError.errorCode != 0) { var myErr = xslDoc.parseError; alert("You have error " + myErr.reason); } else { xslt.stylesheet = xslDoc; var xmlDoc = new ActiveXObject("Msxml2.DOMDocument.3.0"); xmlDoc.async = false; xmlDoc.load("input.xml"); if (xmlDoc.parseError.errorCode != 0) { var myErr = xmlDoc.parseError; alert("You have error " + myErr.reason); } else { xslProc = xslt.createProcessor(); xslProc.input = xmlDoc; xslProc.addParameter("param1", "Hello"); xslProc.transform(); alert(xslProc.output); } } } 
0
source

All Articles