We use a lot of XML fetching in our web applications to fetch information from the server and processing it with JavaScript afterwards. What we normally do is to have a target division hardcoded in the correct location on the page and use JavaScript to add content.
The below example is taken out of context and it utilizes a custom JavaScript object that does all the dirty work and calls the processXML(boolean success) method once the XML is ready for processing. The interesting part is where the HTML is dynamically built using the createElement(String name) and appendChild(Element e) functions.
Searcher.prototype.processXML = function(success) {
// how did we fare ?
if (!success) {
window.status = "Something went wrong while getting the XML while searching - aborting...";
return;
}
try {
// loop databases
var databases = this.getElementsByTagName("database");
if (null == databases) return;
for (var i=0; i<databases.length; i++) {
// get next database
var database = databases[i];
// get the title and path of the database
var db_title = this.getTagValue(database.childNodes, "title");
// get all results for database
var results = null;
for (var j=0; j<database.childNodes.length; j++) {
if (database.childNodes[j].tagName == "results") {
results = database.childNodes[j];
}
}
// get result count
var r_count = results.getAttribute("count");
// create element for db title
var elem_db = document.createElement("div");
elem_db.id = "database" + i;
elem_db.innerHTML = db_title + " (" + r_count + " resulter)";
elem_db.className = "searchresults_database";
elem_db.onmouseover = changeCursor;
elem_db.onmouseout = changeCursor;
elem_db.onclick = clickDatabase;
this.pResults.appendChild(elem_db);
// create element for result section (collapsed)
var elem_results = document.createElement("div");
elem_results.id = "results" + i;
elem_results.className = "searchresults";
elem_results.style.visibility = "hidden";
elem_results.style.display = "none";
this.pResults.appendChild(elem_results);
// loop results
for (var j=0; j<results.childNodes.length; j++) {
if (results.childNodes[j].tagName == "result") {
// get next resultsitem
var r = results.childNodes[j];
// get title and key
var r_title = this.getTagValue(r.childNodes, "title");
var r_key = this.getTagValue(r.childNodes, "key");
var r_link = this.getTagValue(r.childNodes, "link");
// add link anchor
var elem_link = document.createElement("a");
elem_link.href = r_link;
elem_link.className = "searchresult";
elem_link.appendChild(document.createTextNode(r_title));
elem_results.appendChild(elem_link);
elem_results.appendChild(document.createElement("br"));
}
}
}
} catch (exception) {
// some error occured
window.status = "Exception caught in Searcher.processXML(): " + exception.message;
}
}
One thing I found out is that the Microsoft XML component allows for asynchroneous fetching. This allows you to show a progress bar or similar while loading and processing in the background.
function go() {
// set to fetch asynchroneous
this.pXML_data.async = true;
// set callback method
this.pXML_data.onreadystatechange = waitForXml;
// go fish !!
var success = this.pXML_data.load(url);
}
function waitForXml() {
// wait for document to be completely loaded
if (gXML_handler.getXmlIsland().readyState == "interactive") {
// document has been loaded - process it
processXML();
}
}
function processXML() {
// do processing...
}