复杂的Javascript对象解析

时间:2015-08-30 07:30:40

标签: javascript xml-parsing

我有一个xml作为javascript对象。 xml看起来像:

<map-Map>
        <map-Entry>
            <map-Key>
                <std-String value="responseMessage"></std-String>
            </map-Key>
            <map-Value>
                <std-String value="success"></std-String>
            </map-Value>
        </map-Entry>
        <map-Entry>
            <map-Key>
                <std-String value="lastName"></std-String>
            </map-Key>
            <map-Value>
                <std-String value="Page"></std-String>
            </map-Value>
        </map-Entry>
        <map-Entry>
            <map-Key>
                <std-String value="phone"></std-String>
            </map-Key>
            <map-Value>
                <std-String value="860-634-1602"></std-String>
            </map-Value>
        </map-Entry>
        <map-Entry>
            <map-Key>
                <std-String value="fax"></std-String>
            </map-Key>
            <map-Value>
                <std-String value="860-429-5183"></std-String>
            </map-Value>
        </map-Entry>
        <map-Entry>
            <map-Key>
                <std-String value="email"></std-String>
            </map-Key>
            <map-Value>
                <std-String value="larry.page@gmail.com"></std-String>
            </map-Value>
        </map-Entry>
        <map-Entry>
            <map-Key>
                <std-String value="name"></std-String>
            </map-Key>
            <map-Value>
                <std-String value="Alphabets Inc."></std-String>
            </map-Value>
        </map-Entry>
        <map-Entry>
            <map-Key>
                <std-String value="altPhone"></std-String>
            </map-Key>
            <map-Value>
                <std-String value="860-429-0021"></std-String>
            </map-Value>
        </map-Entry>
        <map-Entry>
            <map-Key>
                <std-String value="billingAddress"></std-String>
            </map-Key>
            <map-Value>
                <map-HashMap>
                    <map-Entry>
                        <map-Key>
                            <std-String value="postalCode"></std-String>
                        </map-Key>
                        <map-Value>
                            <std-String value="94043"></std-String>
                        </map-Value>
                    </map-Entry>
                    <map-Entry>
                        <map-Key>
                            <std-String value="addr1"></std-String>
                        </map-Key>
                        <map-Value>
                            <std-String value="1600 Amphitheatre Pkwy"></std-String>
                        </map-Value>
                    </map-Entry>
                    <map-Entry>
                        <map-Key>
                            <std-String value="addr2"></std-String>
                        </map-Key>
                        <map-Value>
                            <std-String value="Mountain View"></std-String>
                        </map-Value>
                    </map-Entry>
                    <map-Entry>
                        <map-Key>
                            <std-String value="state"></std-String>
                        </map-Key>
                        <map-Value>
                            <std-String value="California"></std-String>
                        </map-Value>
                    </map-Entry>
                    <map-Entry>
                        <map-Key>
                            <std-String value="country"></std-String>
                        </map-Key>
                        <map-Value>
                            <std-String value="Unites States"></std-String>
                        </map-Value>
                    </map-Entry>
                    <map-Entry>
                        <map-Key>
                            <std-String value="city"></std-String>
                        </map-Key>
                        <map-Value>
                            <std-String value="California"></std-String>
                        </map-Value>
                    </map-Entry>
                </map-HashMap>
            </map-Value>
        </map-Entry>
        <map-Entry>
            <map-Key>
                <std-String value="dummyList"></std-String>
            </map-Key>
            <map-Value>
                <col-LinkedList>
                    <std-String value="a"></std-String>
                    <std-String value="b"></std-String>
                    <std-String value="c"></std-String>
                </col-LinkedList>
            </map-Value>
        </map-Entry>
        <map-Entry>
            <map-Key>
                <std-String value="firstName"></std-String>
            </map-Key>
            <map-Value>
                <std-String value="Larry"></std-String>
            </map-Value>
        </map-Entry>
        <map-Entry>
            <map-Key>
                <std-String value="companyName"></std-String>
            </map-Key>
            <map-Value>
                <std-String value="Google"></std-String>
            </map-Value>
        </map-Entry>
        <map-Entry>
            <map-Key>
                <std-String value="contact"></std-String>
            </map-Key>
            <map-Value>
                <std-String value="sundar.pichai@gmail.com"></std-String>
            </map-Value>
        </map-Entry>
    </map-Map>  

我有一个javascript对象,看起来像:

{
             'map-Map':{
                 'map-Entry':{
                     'map-Key':{
                       'std-String':{attributes:{value:'firstName'}}
                       },
                     'map-Value':{
                        'std-String':{attributes:{value:'Larry'}}
                       }
                 }
  }
};  

我想要的是将其转换为简单的键值对,例如:

{'responseMessage':'success', 'lastName':'Page', 'billingAddress':{'postalCode':'321021','addr1':'Mountain View'},'firstName':'Larry'}

请帮我解析并创建这样的逻辑,如果它是通用的,那将是很好的,因为节点的嵌套可以存在。提前谢谢。

修改
我试图使用递归,虽然我是新手,但这将进入一个无限循环:

function processedResult(map){
    var resultMap   =   {};
    var mapEntry = map['map-Entry'];
   for(x=0; x<mapEntry.length; x++){
    var value = '';
    var child = mapEntry[x];
    var key = child['map-Key']['std-String']['attributes']['value'];
    var valueNode = child['map-Value'];
    if(Object.keys(valueNode)[0] == 'std-String'){
        value = valueNode['std-String']['attributes']['value'];
    }else if(Object.keys(valueNode)[0] == 'map-HashMap'){
        value = processedResult(valueNode['map-HashMap']);
    }
       resultMap[key] = value;
   }
    return resultMap;
}  

添加整个JS对象:

{"map-Entry":[{"map-Key":{"std-String":{"attributes":{"value":"responseMessage"}}},"map-Value":{"std-String":{"attributes":{"value":"success"}}}},{"map-Key":{"std-String":{"attributes":{"value":"lastName"}}},"map-Value":{"std-String":{"attributes":{"value":"Page"}}}},{"map-Key":{"std-String":{"attributes":{"value":"phone"}}},"map-Value":{"std-String":{"attributes":{"value":"860-634-1602"}}}},{"map-Key":{"std-String":{"attributes":{"value":"fax"}}},"map-Value":{"std-String":{"attributes":{"value":"860-429-5183"}}}},{"map-Key":{"std-String":{"attributes":{"value":"email"}}},"map-Value":{"std-String":{"attributes":{"value":"larry.page@gmail.com"}}}},{"map-Key":{"std-String":{"attributes":{"value":"name"}}},"map-Value":{"std-String":{"attributes":{"value":"Alphabets Inc."}}}},{"map-Key":{"std-String":{"attributes":{"value":"altPhone"}}},"map-Value":{"std-String":{"attributes":{"value":"860-429-0021"}}}},{"map-Key":{"std-String":{"attributes":{"value":"billingAddress"}}},"map-Value":{"map-HashMap":{"map-Entry":[{"map-Key":{"std-String":{"attributes":{"value":"postalCode"}}},"map-Value":{"std-String":{"attributes":{"value":"94043"}}}},{"map-Key":{"std-String":{"attributes":{"value":"addr1"}}},"map-Value":{"std-String":{"attributes":{"value":"1600 Amphitheatre Pkwy"}}}},{"map-Key":{"std-String":{"attributes":{"value":"addr2"}}},"map-Value":{"std-String":{"attributes":{"value":"Mountain View"}}}},{"map-Key":{"std-String":{"attributes":{"value":"state"}}},"map-Value":{"std-String":{"attributes":{"value":"California"}}}},{"map-Key":{"std-String":{"attributes":{"value":"country"}}},"map-Value":{"std-String":{"attributes":{"value":"Unites States"}}}},{"map-Key":{"std-String":{"attributes":{"value":"city"}}},"map-Value":{"std-String":{"attributes":{"value":"California"}}}}]}}},{"map-Key":{"std-String":{"attributes":{"value":"dummyList"}}},"map-Value":{"col-LinkedList":{"std-String":[{"attributes":{"value":"a"}},{"attributes":{"value":"b"}},{"attributes":{"value":"c"}}]}}},{"map-Key":{"std-String":{"attributes":{"value":"firstName"}}},"map-Value":{"std-String":{"attributes":{"value":"Larry"}}}},{"map-Key":{"std-String":{"attributes":{"value":"companyName"}}},"map-Value":{"std-String":{"attributes":{"value":"Google"}}}},{"map-Key":{"std-String":{"attributes":{"value":"contact"}}},"map-Value":{"std-String":{"attributes":{"value":"sundar.pichai@gmail.com"}}}}]}  

在将JS对象提供给此时,我陷入无限循环:

var parse = function (node, obj) {
    //console.dir(node);
    var hashMap;
    // ..
    if ( Object.keys(node)[0] === "map-Map" ) {
        console.log('inside map-Map');
        parse(node["map-Map"],obj);
        return obj;
    }
    // ..
    if ( Object.keys(node)[0] === "map-HashMap" ) {
        console.log('inside map-HashMap');
        //console.log(node);
        hashMap = {};
       _.each(node, function (node) {
            console.log(node);
            parse(node, hashMap);
        });
        //parse(node["map-HashMap"]["map-Entry"], hashMap);
        return hashMap;
    }
    // ..
    if ( Object.keys(node)[0] === "col-LinkedList" ) {
        console.log('inside col-LinkedList');
        return _.reduce(node, function (linkedList, node) {
            linkedList.push(parse(node, {}));
            return linkedList;
        }, []);
    }
    // ..
    if ( Object.keys(node)[0] === "map-Entry" ) {
        console.log('inside map-Entry');
        console.log(node["map-Entry"]);
        for(a=0; a<node["map-Entry"].length; a++){
            obj[parse(node["map-Entry"][a]["map-Key"], obj)] = parse(node["map-Entry"][a]["map-Value"], obj);
        }
        //obj[parse(node["map-Key"], obj)] = parse(node["map-Value"], obj);
        return obj;
    }
    // ..
    if ( Object.keys(node)[0] === "map-Key" ) {
         console.log('inside map-Key');
        return parse(node["map-Key"][0], obj);
    }
    // ..
    if ( Object.keys(node)[0] === "map-Value" ) {
        console.log('inside map-Value');
        return parse(node["map-Value"][0], obj);
    }
    // ..
    if ( Object.keys(node)[0] === "std-String" ) {
        console.log('inside std-String');
        return node["std-String"]["attributes"]["value"];
    }
};

1 个答案:

答案 0 :(得分:2)

var parse = function (node, obj) {
    console.dir(node);
    var hashMap;
    // ..
    if ( node.tagName === "map-Map" ) {
        _.each(node.children, function (node) {
            parse(node, obj);
        });
        return obj;
    }
    // ..
    if ( node.tagName === "map-HashMap" ) {
        hashMap = {};
        _.each(node.children, function (node) {
            parse(node, hashMap);
        });
        return hashMap;
    }
    // ..
    if ( node.tagName === "col-LinkedList" ) {
        return _.reduce(node.children, function (linkedList, node) {
            linkedList.push(parse(node, {}));
            return linkedList;
        }, []);
    }
    // ..
    if ( node.tagName === "map-Entry" ) {
        obj[parse(node.children[0], obj)] = parse(node.children[1], obj);
        return obj;
    }
    // ..
    if ( node.tagName === "map-Key" ) {
        return parse(node.children[0], obj);
    }
    // ..
    if ( node.tagName === "map-Value" ) {
        return parse(node.children[0], obj);
    }
    // ..
    if ( node.tagName === "std-String" ) {
        return node.getAttribute("value");
    }
};

var str = '<map-Map><map-Entry><map-Key><std-String value="responseMessage"></std-String></map-Key><map-Value><std-String value="success"></std-String></map-Value></map-Entry><map-Entry><map-Key><std-String value="lastName"></std-String></map-Key><map-Value><std-String value="Page"></std-String></map-Value></map-Entry><map-Entry><map-Key><std-String value="phone"></std-String></map-Key><map-Value><std-String value="860-634-1602"></std-String></map-Value></map-Entry><map-Entry><map-Key><std-String value="fax"></std-String></map-Key><map-Value><std-String value="860-429-5183"></std-String></map-Value></map-Entry><map-Entry><map-Key><std-String value="email"></std-String></map-Key><map-Value><std-String value="larry.page@gmail.com"></std-String></map-Value></map-Entry><map-Entry><map-Key><std-String value="name"></std-String></map-Key><map-Value><std-String value="Alphabets Inc."></std-String></map-Value></map-Entry><map-Entry><map-Key><std-String value="altPhone"></std-String></map-Key><map-Value><std-String value="860-429-0021"></std-String></map-Value></map-Entry><map-Entry><map-Key><std-String value="billingAddress"></std-String></map-Key><map-Value><map-HashMap><map-Entry><map-Key><std-String value="postalCode"></std-String></map-Key><map-Value><std-String value="94043"></std-String></map-Value></map-Entry><map-Entry><map-Key><std-String value="addr1"></std-String></map-Key><map-Value><std-String value="1600 Amphitheatre Pkwy"></std-String></map-Value></map-Entry><map-Entry><map-Key><std-String value="addr2"></std-String></map-Key><map-Value><std-String value="Mountain View"></std-String></map-Value></map-Entry><map-Entry><map-Key><std-String value="state"></std-String></map-Key><map-Value><std-String value="California"></std-String></map-Value></map-Entry><map-Entry><map-Key><std-String value="country"></std-String></map-Key><map-Value><std-String value="Unites States"></std-String></map-Value></map-Entry><map-Entry><map-Key><std-String value="city"></std-String></map-Key><map-Value><std-String value="California"></std-String></map-Value></map-Entry></map-HashMap></map-Value></map-Entry><map-Entry><map-Key><std-String value="dummyList"></std-String></map-Key><map-Value><col-LinkedList><std-String value="a"></std-String><std-String value="b"></std-String><std-String value="c"></std-String></col-LinkedList></map-Value></map-Entry><map-Entry><map-Key><std-String value="firstName"></std-String></map-Key><map-Value><std-String value="Larry"></std-String></map-Value></map-Entry><map-Entry><map-Key><std-String value="companyName"></std-String></map-Key><map-Value><std-String value="Google"></std-String></map-Value></map-Entry><map-Entry><map-Key><std-String value="contact"></std-String></map-Key><map-Value><std-String value="sundar.pichai@gmail.com"></std-String></map-Value></map-Entry></map-Map>';
var parser = new DOMParser();
var xml = parser.parseFromString(str, "text/xml");    
console.log(JSON.stringify(parse(xml.children[0], {}), null, 4));

我正在使用xml文档和它的节点,但原理应该与解析的JS obj相同。尝试通过它并让我知道它是否是可以理解的。

不确定它是否是交叉brwser,应该使用chrome。

请参阅http://devdocs.io/lodash/了解_.each和_.reduce expl。