Javascript XML Data to Associative Array

2019-06-09 07:01发布

I have XML data which looks like this:

<?xml version='1.0' encoding='ISO-8859-1'?>
<cocktail_list>
<cocktail>
<name> Blue Hawaiian </name>
<ingredient>
<quantity>1</quantity>
<shot>White Rum</shot>
</ingredient>
<ingredient>
<quantity>1</quantity>
<shot>Blue Curacao</shot>
</ingredient>
<ingredient>
<quantity>2</quantity>
<shot>Pineapple Juice</shot>
</ingredient>
<ingredient>
<quantity>1</quantity>
<shot>Coconut Cream</shot>
</ingredient>
</cocktail>
<cocktail>...
</cocktail_list>

Using Javascript I would like to create a nested/associative array (or using objects) to look like: arrayName[Blue Hawaiian[White Rum => 1, Blue Curaco => 2, Pineapple Juice => 1...], name[shot => quantity, ...]]

Now I know how to iterate through my XML, however I don't know how best to convert this into my array.

Any help would be appreciated.

2条回答
冷血范
2楼-- · 2019-06-09 07:33

use jquery.parseXML

var x = $.parseXML(xml_str);
var obj = {};
$(x).find("*").each(function(){
    obj[this.nodeName] = $(this).text;
});

Then you the obj is a json object you can manipulate with obj["cocktail_list"]["cock_tail"]["name"] I didn't consider the array here. For array like cock_tail, you will need to check whether it is already in the obj, and push it in if yes.

查看更多
祖国的老花朵
3楼-- · 2019-06-09 07:44

What you want to do is create an object graph, which you can readily do with a recursive traversal of your XML tree. Every JavaScript object is a map (aka "associative array," but I don't like that term since they aren't arrays). The properties of an object can be accessed via dotted notation with a literal (obj.foo), and via [] notation with a string (obj["foo"]):

var obj = {};            // A blank object
obj.foo = "bar";         // Now it has a property called "foo"
console.log(obj.foo);    // Accessing the property via dotted notation and a literal
console.log(obj["foo"]); // You can also use [] notation and a string
var s = "foo";
console.log(obj[s]);     // And of course the string can be the result of any expression,
                         // including coming from a variable

You can see how the [] notation combined with a string name can readily be used as you traverse your structure, to build up a graph. You'd access the result very similarly to your example, just slight differences. I'd probably opt for the map to be keyed by cocktail name, and then have an ingredients property listing the ingredients (either as an array of objects, or just using the ingredient name as a key). But you can opt not to have the ingredients property and to instead have the cocktail object directly contain the ingredients, for example:

console.log(cocktails["Blue Hawaiian"]["White Rum"].name);       // "shot"
console.log(cocktails["Blue Hawaiian"]["White Rum"].quantity);   // 1

or of course

var bh = cocktails["Blue Hawaiian"];
console.log(bh["White Rum"].name);       // "shot"
console.log(bh["White Rum"].quantity);   // 1

There are lots of different ways you can structure your resulting object graph, depending on how you want to access it and your personal style.

The component parts are:

  1. Creating an object. That's easy:

    var obj = {};
    
  2. Adding a property to an object using dotted notation a property literal:

    obj.propertyName = value;
    
  3. Adding a property to an object using bracketed notation with the name of the property coming from a string expression rather than from a literal:

    obj["propertyName"] = value;
    // or
    var s = "propertyName";
    obj[s] = value;
    // or even
    var s1 = "property", s2 = "Name";
    obj[s1 + s2] = value;
    

    In your case, you might get the property name from an XML nodeName or nodeValue.

  4. Putting an object inside another object. This is actually just assigning to a property, where the value you're assigning is an object reference:

    var outer = {};
    var inner = {};
    inner.foo = "I'm foo";      // Putting the string "I'm foo" on propety `foo`
    outer.bar = inner;          // Putting the `inner` object on the property `bar`
    console.log(outer.bar.foo); // "I'm foo"
    

Since you already know how to traverse your XML, that should get you going on building up an object graph from the results of that traversal. I'm not writing actual code to do it because, again, there are many decisions to make in terms of how you want to structure your object graph that are entirely up to how you want to do it.

查看更多
登录 后发表回答