Monday, May 30, 2011

Render XML into DIV using AJAX and XSL

while trying and playing with some div layers in html and handling XML XSL translations I found out that when you load a XML file containing a link to a XSL file to transform it to HTML in the browser it works fine. However if you juts load it via a standard javascript in a div layer this is not working. you can use javascript to load (pure) html in a DIV a display it within your page, if you load XML it will however not being rendered as one should expect.

For this you will need a small java script. I build the below example. This example is showing how you can load dynamically a XML file in combination with a XSL file, have it transformed into HTML and display it in a DIV element in your page. The nice thing about this approach is that you only have to create your XML file and have the rendering done on your clients workstation. If you update the content of the XML your page will automatically contain new information the next time a user requests the page. A second benefit is that if you want to change the layout of your page you have to only update you XSL style sheet. The example I provide below is quite simple where I use AJAX in combination with XML and XSL to dynamically rendered HTML content of a CD catalog on a page when clicked on a link. The example is not really useful as a page/application however it is showing how you can use the script.

The example contains 2 XML files, 1 XSL file and a HTML file. If you place them all in the same location and open test.html you will see how it is working.

test.html

<html>
<head>
<script>
function loadXMLDoc(dname) {
if (window.XMLHttpRequest) {
xhttp = new XMLHttpRequest();
} else {
xhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xhttp.open("GET", dname, false);
xhttp.send("");
return xhttp.responseXML;
}

function displayResult(source,styledoc) {
xml = loadXMLDoc(source);
xsl = loadXMLDoc(styledoc);
//set a &nbsp to make prevent FF to append the text by double click
document.getElementById("mydiv").innerHTML = "&nbsp;";
// code for IE
if (window.ActiveXObject) {
ex = xml.transformNode(xsl);
document.getElementById("mydiv").innerHTML = ex;
}
// code for Mozilla, Firefox, Opera, etc.
else if (document.implementation && document.implementation.createDocument) {
xsltProcessor = new XSLTProcessor();
xsltProcessor.importStylesheet(xsl);
resultDocument = xsltProcessor.transformToFragment(xml, document);
document.getElementById("mydiv").appendChild(resultDocument);
}
}
</script>
</head>
<body>
<a onclick="displayResult('cdcatalog.xml','cdcatalog.xsl')" href="javascript:void(0);">catalog 1</a>
<a onclick="displayResult('cdcatalog2.xml','cdcatalog.xsl')" href="javascript:void(0);">catalog 2</a>
<div id="mydiv">
</div>
</body>
</html>

cdcatalog.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Di.</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
</catalog>

cdcatalog2.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
<cd>
<title>Some title </title>
<artist>Some artist</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
<cd>
<title>Some othertitle </title>
<artist>The artist</artist>
<country>USA</country>
<company>Columbia</company>
<price>11.40</price>
<year>1985</year>
</cd>
</catalog>

cdcatalog.xsl

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th align="left">Title</th>
<th align="left">Artist</th>
</tr>
<xsl:for-each select="catalog/cd">
<tr>
<td><xsl:value-of select="title" /></td>
<td><xsl:value-of select="artist" /></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Post a Comment