XML to JavaScript Object

70,071

Solution 1

The following function parses XML and returns a JavaScript object with a scheme that corresponds to the XML. XML siblings w/ the same name are collapsed into arrays. nodes with names that can be found in the arrayTags parameter (array of tag name strings) always yield arrays even in case of only one tag occurrence. arrayTags can be omitted. Text nodes with only spaces are discarded.

function parseXml(xml, arrayTags) {
    let dom = null;
    if (window.DOMParser) dom = (new DOMParser()).parseFromString(xml, "text/xml");
    else if (window.ActiveXObject) {
        dom = new ActiveXObject('Microsoft.XMLDOM');
        dom.async = false;
        if (!dom.loadXML(xml)) throw dom.parseError.reason + " " + dom.parseError.srcText;
    }
    else throw new Error("cannot parse xml string!");

    function parseNode(xmlNode, result) {
        if (xmlNode.nodeName == "#text") {
            let v = xmlNode.nodeValue;
            if (v.trim()) result['#text'] = v;
            return;
        }

        let jsonNode = {},
            existing = result[xmlNode.nodeName];
        if (existing) {
            if (!Array.isArray(existing)) result[xmlNode.nodeName] = [existing, jsonNode];
            else result[xmlNode.nodeName].push(jsonNode);
        }
        else {
            if (arrayTags && arrayTags.indexOf(xmlNode.nodeName) != -1) result[xmlNode.nodeName] = [jsonNode];
            else result[xmlNode.nodeName] = jsonNode;
        }

        if (xmlNode.attributes) for (let attribute of xmlNode.attributes) jsonNode[attribute.nodeName] = attribute.nodeValue;

        for (let node of xmlNode.childNodes) parseNode(node, jsonNode);
    }

    let result = {};
    for (let node of dom.childNodes) parseNode(node, result);

    return result;
}

Solution 2

Here's a nice xml2json and json2xml converter:

Here's another one:

Depending on your needs, you might be able to use a standard parser (see http://www.w3schools.com/XML/tryit.asp?filename=tryxml_parsertest2) and xpath (http://www.w3schools.com/xpath/default.asp) - here's an example:

and a few nice tutorials:

Solution 3

Going straight to the point (using node-xml2json):

npm install xml2json

Then, use it:

const parser = require('xml2json');

const obj = parser.toJson(xml, { object: true });

Example:

const parser = require('xml2json');

const xml = '<root><person><name>Bob Dylan</name></person></root>';

const obj = parser.toJson(xml, { object: true });
const { person } = obj.root;
person.name; // Bob Dylan

You can also convert from JSON to XML, and much more.

Solution 4

I wanted a simple Typescript version that didn't create additional #text objects and also disregarded attributes. If that's what you need, here's the code:

export class DomFuncs {

    static parseNode = (node: Node) => {    
        const childNodes = node.childNodes;
        if (childNodes.length === 0) {
            return node.nodeValue;
        } else if (childNodes.length === 1 && childNodes[0].nodeType === Node.TEXT_NODE) {
            return childNodes[0].nodeValue;
        } else {
            const obj = {};
            childNodes.forEach(childNode => {
                const childName = childNode.nodeName;
                const childValue = obj[childName];
                if (childValue !== undefined) {
                    if (Array.isArray(childValue)) {
                        childValue.push(DomFuncs.parseNode(childNode));
                    } else {
                        obj[childName] = [childValue, DomFuncs.parseNode(childNode)];
                    }
                } else {
                    obj[childName] = DomFuncs.parseNode(childNode);
                }
            });
            return obj;
        }
    };

    static xml2obj = (str: string) => {
        const dom = (new DOMParser()).parseFromString(str, 'text/xml')
        const result = {[dom.nodeName]: DomFuncs.parseNode(dom)};
        return result;
    }
}

To use it:

DomFuncs.xml2obj(xmlString);

This script currently disregards XML attributes since my converted object didn't require them. If you need that, let me know and I could update the code.

Share:
70,071
Drew LeSueur
Author by

Drew LeSueur

Updated on March 06, 2021

Comments

  • Drew LeSueur
    Drew LeSueur about 3 years

    I am looking for a JavaScript library that parses an XML string and converts it to a JavaScript object. What are some good ones?