karlkittler
04-19-2006, 06:56 PM
Hello All,
I've been working on the same script for two weeks nearly every day. I have it working almost exactly as I need it to, but there are three issues that I can't seem to figure out.
I think it's a "can't see the forest for the trees" issue, because I've been looking at it for so long. I'm hoping a pair of fresh eyes will see a glaring error or two in what I'm doing.
What I want to do is parse an XML file and put the keys and values into a hash.
I originally started working on this using the method I have now, then I abandoned that thinking there was a better way and used XPath. Xpath works perfect in Mozilla, but I couldn't get IE to work at all, even using xpath_dom.js by Dimitri Glazkov. So I went back to my original plan.
The three problems are #1 erronious replication of hash keys with no data. This can be seen at work at http://d13699489.d91.digitalelite.biz/xmltoarray_cross.php. (this is most problematic in xml_Array['data']['records']['record']['children']['son']['favorite_sport'] vs. xml_Array['data']['records']['record']['children']['son']['favorite_sport2'] because of the errroneous ->['favorite_sport1']. The other places that it happens I could live with, but prefer not to.
#2 using a different XML file, but the same script, it drops or doesn't set slices in the hash. See http://d13699489.d91.digitalelite.biz/xmltoarray_cross2.php (every 'record' should have the same keys, but only the first one is complete).
#3 while minor compared to the other two, the first node of the root node in both XML files are //data/time-date/published/ but the script ignores "published" and puts the data xml_Array['data']['time-date'] in instead.
The output should look like http://d13699489.d91.digitalelite.biz/xml_list2_mozilla_works.php (this is the XPath version, Mozilla Only :mad: )
Any help would be appreciated.
The code involved is:
function xmlToArray(tree) {
if(tree.tagName){
if(tree.hasChildNodes()){
depth++;
for(j=structure.length;j>=depth;j--){
structure.pop(); //remove extra elements
}
structure.push(tree.nodeName);
for(var i=0; i<tree.childNodes.length; i++){
var tmp_array = new Array();
for(k in structure){
tmp_array.push(structure[k]); //put this on the end of the array.
var array_element = eval("xml_Array['"+tmp_array.join("']['")+"']");
if(!array_element){ //if the element does not exist create it.
if(tree.childNodes.length > 1){//if the current node has children
var def_element = eval("xml_Array['"+tmp_array.join("']['")+"'] = new Array()")//create array element.
}else{ //set the value
eval("xml_Array['"+tmp_array.join("']['")+"'] = '"+xmlSafe(tree.childNodes[i].nodeValue)+"'");
break; //we found what we wanted, NEXT!
}
}else{
if(k + 1 > depth){//make sure that we're at the current level.
tmp_array2 = structure;
var count = 0;
while(eval("typeof xml_Array['"+tmp_array2.join("']['")+"'] != 'undefined'")){//other node using this name, need to increment and create a new name.
count++;
var name_test = tmp_array2.pop();//now we have to work backwards.
name_test = name_test.replace(/\d+/g,''); //remove any number from the test name.
tmp_array2.push(name_test+count);
}
}
}
}
xmlToArray(tree.childNodes[i],1);
}
depth--;
}
}else{ //not a tag, data
return tree.nodeValue;
}
}
xmlToArray(tree) is initially passed xmlDoc.documentElement
Full code is in the source of the above URLs.
I've been working on the same script for two weeks nearly every day. I have it working almost exactly as I need it to, but there are three issues that I can't seem to figure out.
I think it's a "can't see the forest for the trees" issue, because I've been looking at it for so long. I'm hoping a pair of fresh eyes will see a glaring error or two in what I'm doing.
What I want to do is parse an XML file and put the keys and values into a hash.
I originally started working on this using the method I have now, then I abandoned that thinking there was a better way and used XPath. Xpath works perfect in Mozilla, but I couldn't get IE to work at all, even using xpath_dom.js by Dimitri Glazkov. So I went back to my original plan.
The three problems are #1 erronious replication of hash keys with no data. This can be seen at work at http://d13699489.d91.digitalelite.biz/xmltoarray_cross.php. (this is most problematic in xml_Array['data']['records']['record']['children']['son']['favorite_sport'] vs. xml_Array['data']['records']['record']['children']['son']['favorite_sport2'] because of the errroneous ->['favorite_sport1']. The other places that it happens I could live with, but prefer not to.
#2 using a different XML file, but the same script, it drops or doesn't set slices in the hash. See http://d13699489.d91.digitalelite.biz/xmltoarray_cross2.php (every 'record' should have the same keys, but only the first one is complete).
#3 while minor compared to the other two, the first node of the root node in both XML files are //data/time-date/published/ but the script ignores "published" and puts the data xml_Array['data']['time-date'] in instead.
The output should look like http://d13699489.d91.digitalelite.biz/xml_list2_mozilla_works.php (this is the XPath version, Mozilla Only :mad: )
Any help would be appreciated.
The code involved is:
function xmlToArray(tree) {
if(tree.tagName){
if(tree.hasChildNodes()){
depth++;
for(j=structure.length;j>=depth;j--){
structure.pop(); //remove extra elements
}
structure.push(tree.nodeName);
for(var i=0; i<tree.childNodes.length; i++){
var tmp_array = new Array();
for(k in structure){
tmp_array.push(structure[k]); //put this on the end of the array.
var array_element = eval("xml_Array['"+tmp_array.join("']['")+"']");
if(!array_element){ //if the element does not exist create it.
if(tree.childNodes.length > 1){//if the current node has children
var def_element = eval("xml_Array['"+tmp_array.join("']['")+"'] = new Array()")//create array element.
}else{ //set the value
eval("xml_Array['"+tmp_array.join("']['")+"'] = '"+xmlSafe(tree.childNodes[i].nodeValue)+"'");
break; //we found what we wanted, NEXT!
}
}else{
if(k + 1 > depth){//make sure that we're at the current level.
tmp_array2 = structure;
var count = 0;
while(eval("typeof xml_Array['"+tmp_array2.join("']['")+"'] != 'undefined'")){//other node using this name, need to increment and create a new name.
count++;
var name_test = tmp_array2.pop();//now we have to work backwards.
name_test = name_test.replace(/\d+/g,''); //remove any number from the test name.
tmp_array2.push(name_test+count);
}
}
}
}
xmlToArray(tree.childNodes[i],1);
}
depth--;
}
}else{ //not a tag, data
return tree.nodeValue;
}
}
xmlToArray(tree) is initially passed xmlDoc.documentElement
Full code is in the source of the above URLs.