How to Convert XML to a JSON-Like JavaScript Object

Craig Buckler
Craig Buckler
Share

In my post How to Create an XML to JSON Proxy Server in PHP we created a system which translated XML messages into Ajax-ready JSON. That’s great if you’re running PHP or another suitable server-side process. But what if you’re limited to JavaScript only? Randomly accessing data from an XML document isn’t fun. You can use DOM or XPath methods, but they’re not as easy as native (JSON-generated) JavaScript object properties such as myobj.list[0].property1. If you’re frequently accessing data from the same XML document, it may be practical to translate it to a JavaScript object first. Ready to write some code?…

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++) { 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++) { 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:
  • No distinction is made between XML attributes and child elements — if they have the same name, an array of items will be returned with the attribute at index 0.
  • XML2jsobj should only be used when it’s practical. If you are retrieving just one or two XML node values, accessing them with DOM or XPath methods would be faster.
  • The code is cross-browser compatible (including IE6) and can process large XML documents quickly. That said, it may not be suitable for every situation. It probably shouldn’t be used in preference to returning JSON from your server.
  • Grab the Code

    Please view the demonstration page or download the code and examples for your own projects. I hope you find it useful — let me know if eases a few XML headaches!

    Frequently Asked Questions on Converting XML to a JavaScript Object

    What is the basic process of converting XML to a JavaScript object?

    The process of converting XML to a JavaScript object involves parsing the XML data and transforming it into a format that JavaScript can understand and manipulate. This is typically done using a parser, which reads the XML data and creates a JavaScript object from it. The parser will interpret the XML tags as properties of the object and the content within the tags as the values of those properties. This allows you to access and manipulate the data in a more intuitive and efficient way.

    How can I use the xml-js package to convert XML to a JavaScript object?

    The xml-js package is a popular tool for converting XML to a JavaScript object. To use it, you first need to install it using npm (Node Package Manager). Once installed, you can require it in your JavaScript file and use its ‘xml2js’ method to convert your XML data. The method takes a string of XML data as its argument and returns a JavaScript object.

    What are some common issues I might encounter when converting XML to a JavaScript object?

    Some common issues you might encounter include malformed XML data, encoding issues, and problems with the structure of the resulting JavaScript object. Malformed XML data can cause the parser to fail, so it’s important to ensure that your XML data is well-formed and valid. Encoding issues can arise if your XML data contains characters that are not supported by JavaScript. Finally, the structure of the resulting JavaScript object may not be what you expect, especially if your XML data is complex or deeply nested.

    How can I convert XML to a JavaScript object using the DOM Parser?

    The DOM Parser is a built-in feature of many web browsers that can be used to parse XML data. To use it, you create a new instance of the DOMParser object and call its ‘parseFromString’ method, passing in your XML data as a string. This will return a Document object, which you can then traverse and manipulate using standard DOM methods.

    Can I convert XML to JSON using JavaScript?

    Yes, you can convert XML to JSON using JavaScript. This is often done in two steps: first, the XML data is parsed into a JavaScript object using a parser like xml-js or the DOM Parser. Then, the JavaScript object is converted to JSON using the JSON.stringify method. This can be useful if you need to work with the data in a format that is more easily manipulated or transmitted than XML.

    How can I handle namespaces when converting XML to a JavaScript object?

    Namespaces in XML can be tricky to handle when converting to a JavaScript object. Some parsers, like xml-js, have options that allow you to preserve namespaces, but this can make the resulting object more complex and harder to work with. Alternatively, you can choose to ignore namespaces, but this may result in data loss if your XML data relies heavily on them.

    Can I convert a JavaScript object back to XML?

    Yes, you can convert a JavaScript object back to XML. This is typically done using a converter, which takes a JavaScript object and generates a string of XML data from it. The properties of the object become the tags of the XML data, and the values of the properties become the content within the tags.

    How can I handle errors when parsing XML data?

    Error handling is an important part of parsing XML data. Most parsers will throw an error if they encounter malformed XML data. You can catch these errors using a try/catch block and handle them appropriately. This might involve logging the error, displaying a message to the user, or attempting to recover from the error in some way.

    Can I parse XML data that is stored in a file?

    Yes, you can parse XML data that is stored in a file. This is typically done by reading the file into a string using a file reader, and then passing that string to your parser. This allows you to work with large amounts of XML data that might not be practical to include directly in your JavaScript code.

    How can I handle special characters in XML data?

    Special characters in XML data, such as ampersands and less-than signs, can cause issues when parsing. These characters need to be escaped in the XML data, typically by replacing them with their corresponding character entities (e.g., & for an ampersand). Most parsers will handle these character entities automatically, converting them back into their original characters in the resulting JavaScript object.