Import XML Document
http://www.quirksmode.org/dom/importxml.html
Working with XML and Javascript
http://www.peachpit.com/articles/article.aspx?p=29307&seqNum=4
On this page I import an XML document and then read out the data and put them in a table on the page.
I think importing XML documents will become more and more important in the future. You can manage the XML document as a kind of database, while the HTML document contains all information about the displaying of the data.
Anyway, try it first by clicking the link and loading some crucial information about the Roman emperors of the Julian-Claudian dynasty. You can also view the XML document separately.
First I import the document emperors.xml, then I enter the XML document through the W3C DOM and extract the data I need, while building a table to display the data.
The script
function importXML()
{
if (document.implementation && document.implementation.createDocument)
{
xmlDoc = document.implementation.createDocument("", "", null);
xmlDoc.onload = createTable;
}
else if (window.ActiveXObject)
{
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.onreadystatechange = function () {
if (xmlDoc.readyState == 4) createTable()
};
}
else
{
alert('Your browser can\'t handle this script');
return;
}
xmlDoc.load("emperors.xml");
}
function createTable()
{
var x = xmlDoc.getElementsByTagName('emperor');
var newEl = document.createElement('TABLE');
newEl.setAttribute('cellPadding',5);
var tmp = document.createElement('TBODY');
newEl.appendChild(tmp);
var row = document.createElement('TR');
for (j=0;j
Importing the XML
First of all I import the XML document and make it accessible through the object xmlDoc
. When the document has finished loading, I want the script createTable()
that construes the table to be executed immediately. Of course, the coding for all this is browser specific.
Clicking the link activates the function importXML
.
function importXML()
{
Mozilla
Netscape imports an XML document through the method document.
. First check if document.
is supported, then check if document.
is supported. Explorer 5 on Mac also supports document.implementation, but not the createDocument method, so it shouldn't execute this script.
if (document.implementation && document.implementation.createDocument)
{
Then create the document and give it an onLoad event handler: as soon as the document has been loaded the script createTable()
is executed, creating the table:
xmlDoc = document.implementation.createDocument("", "", null);
xmlDoc.onload = init;
}
Explorer
Explorer on Windows doesn't support document.implementation . Instead, you must create an Active X Object that will contain the XML document. So we see if the browser can create ActiveXObjects:
else if (window.ActiveXObject)
{
If it does, we can proceed by creating the object
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
Unfortunately there's no onLoad event for this object. To see if it's ready we should use the MS proprietary ReadyStateChange event. I don't quite understand all this myself, but it works. When the onReadyStateChange event handler fires, the readyState
has a value between 1 and 4. 4 means that all data has been received (= onLoad). So if it's 4, start creating the table.
xmlDoc.onreadystatechange = function () {
if (xmlDoc.readyState == 4) createTable()
};
}
Other browsers
If the browser supports neither way, give an alert and end everything:
else
{
alert('Your browser can\'t handle this script');
return;
}
Load document
Finally, load the actual document. Surprisingly, the command for this is the same in both browsers:
xmlDoc.load("emperors.xml");
}
Now we wait for the XML document to be loaded completely, then the function createTable()
is started up.
Strangely, Mozilla sometimes only accepts a URL to the XML file that is relative to the page with the script, which in practice means that you can only access local XML files. Only the Linux version does accept absolute paths in all cases.
You might be able to solve the problem by putting the page containing the script on a real web server instead of a local host. However, this does not help in all cases.
Creating output
This function is entirely specific for the XML document I created. Each XML document is different, each way of displaying the content is different, so the function I wrote is only an example.
The XML document
The XML document consists of nodes named
, which all contain the same children. As an example, this is the structure of the first node:
|
------------------------------------------
| | |
| | |
Augustus 27BC-14AD Peaceful
In the script below I assume that every emperor has this structure. If one hasn't, it could lead to huge problems, but this way I keep the script simple.
Creating the table
Function createTable()
starts by creating an array of all the tags
in the XML document. For each of these tags I want to create a TR containing several TD's with the data.
function createTable()
{
var x = xmlDoc.getElementsByTagName('emperor');
Then we create a new TABLE with CELLPADDING=5. Note the special spelling cellPadding
, Explorer requires this and it doesn't hurt Netscape.
var newEl = document.createElement('TABLE');
newEl.setAttribute('cellPadding',5);
Explorer requires that we also create a TBODY and append it to the table. Don't ask me why, I think TBODY is a completely useless tag, but without it the example doesn't work in Explorer.
var tmp = document.createElement('TBODY');
newEl.appendChild(tmp);
First of all, a row with TH's for the headers. Create a TR
var row = document.createElement('TR');
then go through the childNodes of the first emperor.
for (j=0;j
A problem here: the XML document looks like this:
which means that Netscape considers the empty text node between emperor
and name
as the first child of emperor
. Since these nodes are only a nuisance, we have to check if the nodeType of the childNode is 1 (= it's a tag). If it isn't, continue with the next child:
if (x[0].childNodes[j].nodeType != 1) continue;
Create a container element (TH):
var container = document.createElement('TH');
then read out the name of the childNode (ie. name
, rule
and death
). I want these names to be printed inside the TH. So first I append the name to the TH, then I append the container to the TR
var theData = document.createTextNode(x[0].childNodes[j].nodeName);
container.appendChild(theData);
row.appendChild(container);
}
Finally, append the row to the TBODY tag
tmp.appendChild(row);
Then we go through all elements emperor
and create a TR for each one
for (i=0;i
Go through the childNodes of each emperor, check if it's a node (tag) and create a TD to hold the data
for (j=0;j
Then extract the actual data. Remember that the text inside a tag is the nodeValue of the first childNode of that tag
var theData = document.createTextNode(x[i].childNodes[j].firstChild.nodeValue);
Append the text to the TD and the TD to the TR
container.appendChild(theData);
row.appendChild(container);
}
and when you've finished going through the emperor, append the TR to the TBODY
tmp.appendChild(row);
}
Finally, when you've gone through each emperor, append the TABLE to the special P with ID="writeroot" I created:
document.getElementById('writeroot').appendChild(newEl);
}
and a table has been magically created.
0 comments:
Post a Comment