0

I have a program that we use at my work, which outputs its data in to XML files (several of them). I am trying to develop an HTA (yes an HTA, i'm sorry) to read these files and process their data. Unfortunately there are a number of XML files and I only need to read a few specific ones, so I am trying to write a generic "XML to array" function.

I got it to read the XML file and now I want to process the file into a 2d Array. However, since I am using a recursive function I seem to lose data. Here is the function:

NodesToArray = function (xmlDOC){

    //Must redeclare "i" with each recursion, or it won't work correctly. ie: for(VAR i = 0...  
    for(var i = 0; i < xmlDOC.length ; i++){

        //Just because it has a child still do the check.
        if(xmlDOC[i].childNodes.length > 1){

             //Recursively run the function.
             var ReturnArray = NodesToArray(xmlDOC[i].childNodes);
             //alert(ReturnArray + " " );   

             if(ReturnArray) return ReturnArray;

     }else{

    //Check to see if the node has a child node, if not and a child node is called, it will error out and stop
    if(xmlDOC[i].hasChildNodes() == true){

        return xmlDOC[i].firstChild.nodeValue;

         }
       }    
     }  
   } 

Where I return the first child value I put an alert and was able to see all the data I wanted. Of course when I set it up I found it wasn't keeping the data. I've done a ton of reading and have been pounding my head against my desk and still can't come up with anything.

I've googled, searched this site, and consulted many forums, and can't find anything that would work for me. I post here reluctantly as I am at a dead end. Thanks for any help and I will provide any additional information as I can.

Just a note, but I would like to be able to do this without any libraries (specifically jQuery). The HTA doesn't seem to support a lot of newer Javascript. I'm not a professional coder by any means and learn by doing everything from scratch.

Not sure how to set the solution, but I found it

function NodesToArray(xmlDOC, returnArray){
    for(var i = 0; i < xmlDOC.length ; i++){
        if(xmlDOC[i].childNodes.length > 1){
            returnArray[returnArray.length] = NodesToArray(xmlDOC[i].childNodes, []);
        }else{
            if(xmlDOC[i].hasChildNodes() == true){      
                returnArray[returnArray.length] = (xmlDOC[i].firstChild.nodeValue);
            }
        }
    }
    return returnArray;
}

getArray = NodesToArray(getXML.getElementsByTagName(tagName)[0].childNodes,[]);

Thanks for the help!

Josh
  • 3
  • 3

2 Answers2

1

The general way of retrieving data recursively in the same container is to write two function:

  1. First one is the one that you call and which returns the array
  2. Second one is called by first function and does the recursion. To be able to put the data in the same array that function has to take it as parameter.

Here is some pseudo code

getData(node) {
   _2D_array = new array[][];
   getData(node, _2D_array, 0);
   return array;
}

getData(node, _2D_array, depth) {
   if(node) { // end of recursion ?
       _2D_array[depth].add(...); // populate from node
       getData(node.next, _2D_array, depth++);
   }
}
A4L
  • 17,353
  • 6
  • 49
  • 70
  • I tried this, but when ever I call the function it only calls the second function. How do I differentiate them? – Josh Apr 16 '13 at 12:44
  • both functions are differentiated through thiere signatures `node` vs `node, array`, the second function call itself -> `node, array` . You have to take care that the array has always enoough space / can expand. – A4L Apr 16 '13 at 12:57
  • It might be that I am running this in an HTA but when I rename the second function (using your example) to getData2, or in my case NodesToArray2, it gets the data, although it puts it in a 1 dimensional array instead of multidimensional. – Josh Apr 16 '13 at 13:18
  • @Josh edited the pseudo code to deal with 2D array. You have to init the 2D array and make sure that it can expand, since you call the function recursively you cannot know at init time how big the resulting array will be. – A4L Apr 16 '13 at 13:54
  • I found a solution, however I was able to get it using 1 function, although your pseudo code is what led me to it. Thanks for the help (solution has been edited up top.) – Josh Apr 16 '13 at 13:58
0

Your program exits when the first element is processed because the function returns. A function can only return once. You need to move the return statements outside the loop so that the loop completes.

Erwan Legrand
  • 4,148
  • 26
  • 26