Převeďte XML na JSON pomocí JavaScriptu

Pokud mě sledujete na Twitteru, víte, že jsem pracoval na super přísně tajná mobilní aplikace využívající Appcelerator Titanium. Zkušenost byla skvělá: používání JavaScriptu k vytváření snadno zapisovatelných a testovatelných nativních mobilních aplikací bylo zábavné. Moje mobilní aplikace se připojuje k mnoha rozhraním API sociálních sítí, z nichž některá poskytují pouze odpověď XML. Můj mini „rámec“ používá JSON k dynamickému vytváření widgetů, takže jsem potřeboval způsob, jak přeměnit XML na JSON. Našel jsem mnoho řešení, ale žádné z nich nefungovalo. Po úpravě stávající funkce jsem našel řešení, které funguje skvěle.

JavaScript

Je důležité zdůraznit, že objekt Titanium.XML.DOMDocument společnosti Titanium implementuje struktury na úrovni DOM2. Zde je kouzelný kód XML na JSON:

// 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;
};

Hlavní změnou, kterou jsem potřeboval implementovat, bylo použití attributes.item(j) místo attributes[j] že většina skriptů, které jsem našel, používala. S touto funkcí XML, který vypadá takto:

<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>

...se stane funkčním objektem JavaScriptu s následující strukturou:

{
	"@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
				}
			}
		}
	]
}

Odtud můžete použít objekt JavaScriptu, jak uznáte za vhodné. Pokud chcete JavaScript ve formátu JSON řetězce, můžete kódovat:

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

Tato funkce byla mimořádně užitečná, protože mi umožnila rychle ignorovat XML a místo toho použít JSON. Funkce funguje dobře při strukturování atributů a polí vnořených podřízených uzlů. Mějte to po ruce; v určitém okamžiku možná budete muset převést XML na JSON!