The XML2jsobj Function
We’re going to write a function which recursively analyzes each node of an XML document’s DOM tree and returns a JavaScript object. The function is passed a starting node — which will normally be the root documentElement — and returns an object (internally named data):
- function XML2jsobj(node) {
- var data = {};
We’ll now define an Add() function within XML2jsobj. This appends a name/value pair to the data object, e.g. data[name] = value. However, if that name already exists, it must convert data[name] to an array so two or more values can be applied:
- // append a value
- function Add(name, value) {
- if (data[name]) {
- if (data[name].constructor != Array) {
- data[name] = [data[name]];
- }
- data[name][data[name].length] = value;
- }
- else {
- data[name] = value;
- }
- };
We now require a loop to examine the XML node’s attributes (e.g. <node attrib1="1" attrib2="2">) and append them to the data object using the Add() function:
- // element attributes
- var c, cn;
- for (c = 0; cn = node.attributes[c]; c++) {
- Add(cn.name, cn.value);
- }
The next loop examines all child nodes. Comments and white space are ignored but, if a child contains a single item of textual data, it’s appended to the data object using Add(). If that child has its own children, we recursively call XML2jsobj to generate the object:
- // child elements
- for (c = 0; cn = node.childNodes[c]; c++) {
- if (cn.nodeType == 1) {
- if (cn.childNodes.length == 1 && cn.firstChild.nodeType == 3) {
- // text value
- Add(cn.nodeName, cn.firstChild.nodeValue);
- }
- else {
- // sub-object
- Add(cn.nodeName, XML2jsobj(cn));
- }
- }
- }
Finally, we return the data object to our calling function:
- return data;
Converting XML
Our Ajax call can retrieve XML from a web service:
- // example XML feed
- var url = "example.xml";
- // AJAX request
- var xhr = (window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"));
- xhr.onreadystatechange = XHRhandler;
- xhr.open("GET", url, true);
- xhr.send(null);
Our XMLHttpRequest onreadystatechange handler receives the XML data and converts it to JavaScript object:
- // handle response
- function XHRhandler() {
- if (xhr.readyState == 4) {
- var obj = XML2jsobj(xhr.responseXML.documentElement);
- // do something with our returned data...
- console.log(obj);
- xhr = null;
- }
- }
So, if example.xml returned the following XML data:
- <?xml version="1.0"?>
- <statuses>
- <status id="one">
- <id>1</id>
- <text>Hello!</text>
- </status>
- </statuses>
XML2jsobj(xhr.responseXML.documentElement) would return the following object:
- {
- status: {
- id: ["one", 1],
- text: "Hello!"
- }
- }
You can therefore use obj.status.text to retrieve the “Hello!” text.
Buyer Beware!
A few notes about XML2jsobj:
Grab the Code
Please download the code and examples for your own projects.