I am working on a Javascript function which takes an XML document and creates a multidimensional (as needed) associative array. Inside the function, the array builds properly however upon returning the Array object, it returns an empty array.
Interesting to note, if I use the push method, and push a literal Array in the form {"index": index, "value":value} rather than using the assignment operator (array[index]=value) it works just fine
For testing I am using the following XML node object (Level_1_node):
<Level_1>
<Level_2>VALUE</Level_2>
</Level_1>
Here is the function:
function get_array_from_XML(XML_node){
var XML_array = new Array();
var child_node;
for(var i=0; i<XML_node.childNodes.length; i++){
child_node = XML_node.childNodes[i];
if(child_node.childNodes[0]){
if (child_node.childNodes[0].nodeType == 3){
XML_array[child_node.nodeName] = child_node.childNodes[0].nodeValue;
} else {
XML_array[child_node.nodeName] = get_array_from_XML(child_node);
}
}
}
dump(XML_array); //for my debugging, alerts "LEVEL_2 => VALUE", so everything seems fine
return XML_array;
}
The follow method works, however the return format is undesirable:
function get_array_from_XML_using_push(XML_node){
var XML_array = new Array();
var child_node;
for(var i=0; i<XML_node.childNodes.length; i++){
child_node = XML_node.childNodes[i];
if(child_node.childNodes[0]){
if (child_node.childNodes[0].nodeType == 3){
XML_array.push({
"index" : child_node.nodeName,
"value" : child_node.childNodes[0].nodeValue
});
} else {
XML_array.push({
"index" : child_node.nodeName,
"value" : get_array_from_XML_using_push(child_node)
});
}
}
}
dump(XML_array); //shows the fully populated array
return XML_array;
}
Now when I run get_array_from_XML(Level_1_node)
it returns an empty array, but get_array_from_XML_using_push(Level_1_node)
returns
{0 => {"index" => "Level_2", "value" => "VALUE"}}
Very frustrating. Any insight is welcome.
Change new Array()
to new Object()
. The Array
constructor is not for associative arrays; it's for numerically indexed arrays only. Objects themselves double as associative arrays in JavaScript.
function get_array_from_XML(XML_node){
var XML_array = new Object();
// -------------------^
var child_node;
for(var i=0; i<XML_node.childNodes.length; i++){
child_node = XML_node.childNodes[i];
if(child_node.childNodes[0]){
if (child_node.childNodes[0].nodeType == 3){
XML_array[child_node.nodeName] = child_node.childNodes[0].nodeValue;
} else {
XML_array[child_node.nodeName] = get_array_from_XML(child_node);
}
}
}
dump(XML_array); //for my debugging, alerts "LEVEL_2 => VALUE", so everything seems fine
return XML_array;
}
Have a look at the following example:
var colors = new Object();
colors['red'] = '#f00';
colors['green'] = '#0f0';
colors['blue'] = '#00f';
colors['black'] = '#000';
colors['white'] = '#fff';
conosle.log(colors['red']); // => #f00
conosle.log(colors['green']); // => #0f0
conosle.log(colors['white']); // => #fff
// Use for..in or Object.keys to iterate over an object
for (var key in colors) {
console.log(key, colors[key]);
}
// Logs all colors and their corresponding code
Object.keys(colors).forEach(function(key) {
console.log(key, colors[key]);
});
// Also logs all colors and their corresponding code
Note that colors['red'] = '#f00';
is identical to colors.red = '#f00';
. The square bracket notation is only really needed when you want to use a string which is an invalid identifier or when you want to use the value of a variable as a property name.