简体   繁体   中英

Convert JavaScript XML DOM Object to Object with certain structure

I have a large XML DOM Object which was parsed via jQuery's $.parseXML function, returning a JavaScript DOM Object. With this XML I want to create an normal JavaScript Object with the following structure:

{
    name: 'my_tree',
    children: [
        { name: 'hello' },
        { name: 'wat' },
        {
            name: 'child_folder',
            children: [
                {
                    name: 'child_folder',
                    children: [
                        { name: 'hello' },
                        { name: 'wat' }
                    ]
                },
                { name: 'hello' },
                { name: 'wat' },
                {
                    name: 'child_folder',
                    children: [
                        { name: 'hello' },
                        { name: 'wat' }
                    ]
                }
            ]
        }
    ]
}

The original XML would look something like this:

<my_tree>
    <hello></hello>
    <wat></wat>
    <child_folder>
        <child_folder>
            <hello></hello>
            <wat></wat>
        </child_folder>
        <hello></hello>
        <wat></wat>
        <child_folder>
            <hello></hello>
            <wat></wat>
        </child_folder>
    </child_folder>
</my_tree>

I have tried something like the code below, but to no avail:

function xmlDomToObject(domObject) {
    var result = {children: []};
    for (var i = 0; i < domObject.length; i++) {
        if (domObject[i].nodeName == "#text") {
            continue;
        }

        result['name'] = domObject[i].nodeName;
        result['children'].push(xmlDomToObject(domObject[i].childNodes));
    }

    return result;
}

var xmlObject = xmlDomToObject(xmlDomObject.childNodes);

One possible approach goes below. Using children (instead of childNodes ) property allows to bypass text nodes and check Elements only:

function parseXml(node) {
  const el = {
    name: node.nodeName
  };

  const children = Array.prototype.map.call(node.children, parseXml);
  // ES6: const children = [...node.children].map(parseXml);
  if (children.length) {
    el.children = children;
  }

  return el;
}

You can use it as is, just remember to pass documentElement property of $.parseXML result - and not the result itself.

 const xmlStr = `<my_tree> <hello></hello> <wat></wat> <child_folder> <child_folder> <hello></hello> <wat></wat> </child_folder> <hello></hello> <wat></wat> <child_folder> <hello></hello> <wat></wat> </child_folder> </child_folder> </my_tree>`; const xml = $.parseXML(xmlStr); const parsed = parseXml(xml.documentElement); console.log(parsed); function parseXml(node) { const el = { name: node.nodeName }; // const children = [...node.children].map(parseXml); const children = Array.prototype.map.call(node.children, parseXml); if (children.length) { el.children = children; } return el; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM