17 Replies Latest reply on Jun 12, 2007 7:15 AM by hciguy

    Building data storage

    hciguy Level 1
      Okay. I made an XML Parses in AS 3.0 that reads an entire XML structure, every child and everything. Right now I am working on the data storage class for it. Basically I need to do this but dynamically:

      var dog:String = "stuff";
      var cat:String = "otherstuff";

      var thisTest:Array = [];
      thisTest[dog] = ["this", "that", "other"];
      thisTest[dog][cat] = [0,1,2];

      trace("Here: " + thisTest.stuff.otherstuff);

      I need to be able to make an associate array (that is associative, right? Not multi-dimensional?) that holds a varying number of levels. So I may have thisTest.stuff.otherstuff.otherother.someother ... I need to be able to build that and right now I am having a brain freeze from coding AS all day long. Basically I have these nodes which have a name, level in the hierarchy, attributes, etc. and I need to store them in an array. I want to be able to access them using dot syntax....anyone?

      Thanks!
        • 1. Re: Building data storage
          hciguy Level 1
          Basically, after looking around, I think I need to create a multi-dimensional array dynamically. Any help would be greatly appreciated. I know how to hard code a md array but how to do it dynamically...

          Since I am building it off of an XML document, I need to be able to go deep as well as wide. I have no problem doing the thisArray[variable] = [var1, var2, var3, etc] part but how to get thisArray[variable][variable] or thisArray[variable][variable][variable] dynamically in such a way that the number of arrays there can be dynamic....

          Thanks guys.
          • 2. Re: Building data storage
            kglad Adobe Community Professional & MVP
            :

            • 3. Re: Building data storage
              hciguy Level 1
              Hi kglad. Thanks for your help....

              Isn't the code you attached only going to get me 2 levels deep - i.e. array\[\i] and array\[\i][j]? I need a potentially unlimited number of levels deep depending on how many levels the XML structure has. Perhaps I am not explaining it perfectly but I need to nest dynamically so it seems to me I can't hard code any of the nested arrays....

              Does that make sense?
              • 4. Re: Building data storage
                kglad Adobe Community Professional & MVP
                yes, i understand now. but you'll need to know something about the structure of your xml file or you won't be able to parse it. i can't see creating a flash parser that extracts data from all possible xml files.

                it might be possible to create a general parser, but i can't see a way to do that.
                • 5. Re: Building data storage
                  AspireMan Level 1
                  what you need is to write a recursive function. Basically, if your xml structure looks like this:

                  <elements><element attribute1=""><element attribute1="" /></element></elements>

                  Then your function will start with your root node and create what you want by traversing each node like so. Be very careful that you eventually will hit a case where this function will return. It's very easy to create recursion that kills your machine.

                  function traverseXML(currentArray:Object, curNode:XMLNode):Object {
                  currentArray[curNode.nodeName] = curNode.attributes.attribute1;
                  var childNode:XMLNode = curNode.firstChild;
                  while (childNode != null) {
                  currentArray[curNode.nodeName] = traverseXML(currentArray[curNode.nodeName], childNode);
                  }
                  return currentArray;
                  }

                  myArray:Object = new Object;
                  myArray = traverseXML(myArray, myXML.firstChild);

                  Well... this is untested and probably won't return the exact type of structure you want, but hopefully is shows a little about how recursion should traverse your structure.

                  PS: you seem to be using objects for your "arrays" because you have strings for keys - hence my Object types
                  • 6. Re: Building data storage
                    hciguy Level 1
                    Well I have the XML Parser class written. As far as I can tell, it traverses the whole XML structure and finds each node along with the level it is at, its parent, its attributes, etc. Maybe it won't work with every XML file but as far as I can tell, it should. I've changed the structure of it and it still finds every node properly.

                    AspireMan, the example you gave me - as far as I can tell - just loads one nested array? Here is where it looks like your loading code is:

                    while (childNode != null) {
                    currentArray[curNode.nodeName] = traverseXML(currentArray[curNode.nodeName], childNode);
                    }

                    But won't that always load into the first nested array of currentArray? It'll never go deeper? I.e. it'll be currentArray[nest1] but never currentArray[nest1][nest2]? I need to do dynamic nesting, you know what I mean?

                    Maybe something like:

                    var allNodes:Array = new Array;
                    for(var w=0; w<thisXML.children().length(); w++){
                    allNodes = allNodes[allNodes[w]];
                    }

                    Would that add a new nested array? I don't know...

                    I feel like I'm not explaining it too well.
                    • 7. Re: Building data storage
                      hciguy Level 1
                      Just a *bump*
                      • 8. Re: Building data storage
                        hciguy Level 1
                        *bump*
                        • 9. Re: Building data storage
                          AspireMan Level 1
                          Sorry for the delay. I don't usually stick around on weekends.

                          I missed the part where you are using your own parser. My function is an example of traversing an xml structure that was parsed natively by flash.

                          If you look closely at what is happening, you'll see that the recursive function should return an array. In the function, that array element corresponds to a certain node. I stuck a quick one-liner in there to show that you would then populate that element in your array. When you then loop through the node's children, you are calling the same function on the children. Thus, the array that is returned is the child's array with that child's information and all of it's children's information. However, you can't use exactly what I wrote as it does not really populate all of the attributes that the element may have (you'll need a for loop to do that) and it's passing the same element for the child to populate which would over-write the current node information with the child's information. I was trying more to show how the recursion could traverse the tree passing along current state so you can go "infinitely" deep without knowing everything about your nodes beforehand.

                          My key point is that when you do this (notice added brackets):
                          currentArray[curNode.nodeName][] = traverseXML(currentArray[curNode.nodeName], childNode);

                          The array that is returned is the same processing on the child node, which will then go check out its child and so forth until no more children are found.

                          Hope this helps.
                          • 10. Re: Building data storage
                            hciguy Level 1
                            Hey Aspire,

                            Thanks for writing back. I am a-okay on the parsing of data from the tree regardless of its structure. When I said I was using my own parser, I just meant I wrote a class that does - should - traverse the tree and get all the children regardless of depth. My huge problem now - and I am s-t-u-c-k - is how to store that data?

                            If I were hard-coding it, I'd use nested arrays like the following:

                            nodes["level1a"] = [name, attributes];
                            nodes["level1b"] = [name,attributes];
                            nodes["level1c"]["level2"] = [name, attributes];
                            nodes["level1c"]["level2b"] = [name, attributes];
                            nodes["level1c"]["level2b"]["level3"] = [name, attributes];
                            nodes["level1d"] = [name,attributes];

                            But I can't hard-code it since I don't know how deep the tree goes. Is there a way to make those nested arrays dynamically? Is there some other way to store the data? I thought of giving each node a unique ID, then storing it all in an array, but then I have to sort and parse to find nodes that are children of nodes, etc. If I could create the same sorts of nested arrays as above then I could allow access in the FLA via dot syntax...any ideas?

                            ANYTHING would be great since I am stuck.

                            Thanks so much!!
                            • 11. Re: Building data storage
                              AspireMan Level 1
                              Truthfully, the best way to keep this data is in the DOM created from the xml. You are attempting to duplicate this structure using arrays. However, the recursive approach is the only way to do it.

                              Here's another example - NOT the finished product, but an example of the theory behind what you need to do:

                              //I'm putting in the depth param in case you'd rather use level+depth in your naming conventions
                              function traverseXML(node:XMLNode, depth:Number):Object {
                              var myObj:Object = new Object;

                              //this will create a copy of the xml node attributes
                              for (i in node.attributes) {
                              myObj = node;
                              }

                              myObj['name'] = node.nodeName;

                              //now create child objects and attach them directly to this object
                              var curNode:XMLNode = node.firstChild;
                              while (curNode != null) {
                              myObj[curNode.nodeName] = traverseXML(curNode, depth+1);
                              }

                              return myObj;
                              }

                              You should notice that you are not creating a single array. This creates an array with an attached child array for each child - as deep as the xml goes.

                              Good luck!
                              • 12. Building data storage
                                hciguy Level 1
                                1. You said: "Truthfully, the best way to keep this data is in the DOM created from the xml." Are you saying rather than store the tree data I should just search the DOM whenever I need something from it?

                                2. So you're saying that what you gave me will allow me to go as deep as I want to with nested arrays? I don't see how it doesn't go deeper than one deep...

                                It'll give me: nodes.nodes1b.nodes1b2 ?

                                Sorry if this all is basic but I am just trying to figure out what is best to get this done.

                                Thanks!
                                • 13. Re: Building data storage
                                  AspireMan Level 1
                                  yes... the point of the recursion is to go deeper and deeper and the point of returning the current object is to stack those objects on top of each other. Give it a whirl and see what happens... You'll likely have to make some changes to get it perfect.
                                  • 14. Re: Building data storage
                                    hciguy Level 1
                                    So this code: myObj[curNode.nodeName] = traverseXML(curNode, depth+1);

                                    That will nest it? To me it looks like only one level cause all it has is myObj[onelevelhere]. Somehow it'll turn into myOby[onelevelhere][deeperonehere] , as opposed to myObj[onelevelhere1] and myObj[onelevelhere2] etc?

                                    What am I missing about the logic?

                                    Thanks SO MUCH for your help!
                                    • 15. Re: Building data storage
                                      AspireMan Level 1
                                      wow... you need to go through an example.

                                      this:
                                      myObj[curNode.nodeName] = traverseXML(curNode, depth+1);

                                      does not equal this:
                                      myObj[onelevelhere] = [ my stuff ]

                                      The left side of my call is assigning to an object created in this function. The right side is assigning an object returned from this function run on its own child node. If you have never used recursion before, go through an example on paper to see how it works.
                                      • 16. Re: Building data storage
                                        hciguy Level 1
                                        I apologize. I am new to recursion.

                                        I'll work on it. Thanks for helping!
                                        • 17. Re: Building data storage
                                          hciguy Level 1
                                          I feel stupid. So actually all I need to do is load the XML and then access it using the DOM?

                                          Blah.

                                          Thanks guys.