David Walsh Blog

Convert XML to JSON with JavaScript

If you follow me on Twitter, you know that I’ve been working on a super top secret mobile application using Appcelerator Titanium.  The experience has been great:  using JavaScript to create easy to write, easy to test, native mobile apps has been fun.  My mobile app connects to numerous social network APIs, some of which only provide an XML response.  My mini “framework” uses JSON to dynamically create widgets so I’ve needed a way to turn XML into JSON.  I found many solutions but none of them worked.  After tweaking an existing function, I’ve found a solution that works great.

The JavaScript

It’s important to point out that Titanium’s Titanium.XML.DOMDocument object implements DOM2-level structures.  Here’s the magic XML to JSON code:


// Changes XML to JSON
function xmlToJson(xml) {
	
	// Create the return object
	var obj = {};

	if (xml.nodeType == 1) { // element
		// do attributes
		if (xml.attributes.length > 0) {
		obj["@attributes"] = {};
			for (var j = 0; j < xml.attributes.length; j++) {
				var attribute = xml.attributes.item(j);
				obj["@attributes"][attribute.nodeName] = attribute.nodeValue;
			}
		}
	} else if (xml.nodeType == 3) { // text
		obj = xml.nodeValue;
	}

	// do children
	if (xml.hasChildNodes()) {
		for(var i = 0; i < xml.childNodes.length; i++) {
			var item = xml.childNodes.item(i);
			var nodeName = item.nodeName;
			if (typeof(obj[nodeName]) == "undefined") {
				obj[nodeName] = xmlToJson(item);
			} else {
				if (typeof(obj[nodeName].push) == "undefined") {
					var old = obj[nodeName];
					obj[nodeName] = [];
					obj[nodeName].push(old);
				}
				obj[nodeName].push(xmlToJson(item));
			}
		}
	}
	return obj;
};

The major change I needed to implement was using attributes.item(j) instead of the attributes[j] that most of the scripts I found used.  With this function, XML that looks like:


<ALEXA VER="0.9" URL="davidwalsh.name/" HOME="0" AID="=">
	<SD TITLE="A" FLAGS="" HOST="davidwalsh.name">
		<TITLE TEXT="David Walsh Blog :: PHP, MySQL, CSS, Javascript, MooTools, and Everything Else"/>
		<LINKSIN NUM="1102"/>
		<SPEED TEXT="1421" PCT="51"/>
	</SD>
	<SD>
		<POPULARITY URL="davidwalsh.name/" TEXT="7131"/>
		<REACH RANK="5952"/>
		<RANK DELTA="-1648"/>
	</SD>
</ALEXA>


…becomes workable a JavaScript object with the following structure:


{
	"@attributes": {
		AID: "=",
		HOME:  0,
		URL: "davidwalsh.name/",
		VER: "0.9",
	},
	SD = [
		{
			"@attributes": {
				FLAGS: "",
				HOST: "davidwalsh.name",
				TITLE: A
			},
			LINKSIN: {
				"@attributes": {
					NUM: 1102
				}
			},
			SPEED: {
				"@attributes": {
					PCT: 51,
					TEXT: 1421
				}
			},
			TITLE: {
				"@attributes": {
					TEXT: "David Walsh Blog :: PHP, MySQL, CSS, Javascript, MooTools, and Everything Else",
				}
			},
		},
		{
			POPULARITY: {
				"@attributes": {
					TEXT: 7131,
					URL: "davidwalsh.name/"
				}
			},
			RANK: {
				"@attributes": {
					DELTA: "-1648"
				}
			},
			REACH: {
				"@attributes": {
					RANK = 5952
				}
			}
		}
	]
}

From here you can use the JavaScript object however you see fit. If you’d like the JavaScript in string JSON format, you can code:


// Assuming xmlDoc is the XML DOM Document
var jsonText = JSON.stringify(xmlToJson(xmlDoc));

This function has been extremely useful in allowing me to quickly disregard XML and use JSON instead.  The function works well when structuring attributes and arrays of nested child nodes.  Keep this handy;  at some point you may need to convert XML to JSON!