0

I'm trying create an visual representation of the evolution of life using processing 3 on a mac - I'm using XML to organize the tree-like data. Here's how I'm organizing my XML code:

<?xml version="1.0"?>
<A>
    <animal>Bacteria</animal>
    <B>
        <animal>Archea</animal>
        <C>
            <animal>Foraminifera</animal>
            <D>
                <animal>Green Algae</animal>
                <E>
                    Mosses
                </E>
            </D>
            <J>
                <animal>Yeast</animal>
                <animal>Sponges</animal>
                <animal>Corals</animal>
                <K>
                    <L>RoundWorms</L>
                    <V>SchinoDerms</V>
                </K>
            </J>
        </C>
    </B>
</A>

The letters represent branching off points in time, and the "animal" tags are animals that existed in that particular time period ( I have to add more info, such as "time", but I want to solve this problem first ).

I'm trying to traverse through the XML doc but cannot figure out how to get further than the first child node ( "B" ). In the end I want this to resemble a tree of breakpoints with animals branching off of their respective time periods ( "Bacteria" branches off from breakpoint "A", "Archea" branches off from breakpoint "B", etc. )

I think if I can figure out how to get past the first child I'd be all set - any ideas?

pnuts
  • 58,317
  • 11
  • 87
  • 139
max rose
  • 3
  • 1
  • AddNode code on following webpage should work. Use a treeview : http://stackoverflow.com/questions/28976601/recursion-parsing-xml-file-with-attributes-into-treeview-c-sharp – jdweng Sep 10 '15 at 19:57

1 Answers1

0

You should start with the XML reference and examples such as LoadSaveXML/XMLYahooWeather under Examples > Topics > Advanced Data

You can do a basic traversal through your nodes by calling getChilren() which returns an XML array. At this stage it should be simple enough to loop through this array and access data from each child XML instance at this level:

XML xml;
void setup(){

  xml = loadXML("data.xml");
  xml.trim();

  XML[] level0 = xml.getChildren();
  for(int i = 0; i < level0.length; i++){
    println("level0["+i+"]:" + level0[i]);
  }

}

Note1: The above example works with Processing 3, but may not work with older versions as the XML API changes (for example the trim() function might be missing). The trim() function should remove white spaces(new lines, tabs, etc.) otherwise, empty lines might be considered XML nodes. Always check to avoid surprises because due to white space in XML.

Note2 The examples in this answers assume the xml you posted is saved as data.xml in the sketch folder you're trying to run the code in. Feel free to rename that to what your XML file is actually called

Ok, so now you go through the first level, but how do you go to the next one ? It's actually not that bad. As you loop through each child XML node you can check if it hasChildren(), in which case, you repeat the prior operations:

  1. get the children xml nodes
  2. loop through each child xml node

(At this stage this would be 'grand' children:

XML xml;

void setup(){
  xml = loadXML("data.xml");
  xml.trim();

  XML[] level0 = xml.getChildren();
  for(int i = 0; i < level0.length; i++){
    println("level0["+i+"]:" + level0[i]);

    //we need to go deeper...but can we ?
    if(level0[i].hasChildren()){
      XML[] level1 = level0[i].getChildren();

      for(int j = 0; j < level1.length; j++){
          println("\tlevel1["+j+"]:" + level1[j]);
      }

    }
  }

}

You should be able to safely repeat the process to drill down further.

As you go deeper and deeper there's something fun to play with: recursive functions. If you're not familiar with writing your own functions from scratch yet, you should first get a hang of that.

They've got a few things in common with variables:

  • functions also have a type (called the return type)
  • functions also have a name

But what do mainly do is group a set of instructions. Depending on what these instructions do, they may or may not return a result, which determines the functions type.

The simplest are functions that don't return anything (therefore the return type is void). You've probably used void setup(){} before, right ? :)

Functions create a separate scope(within the {} symbols) so variables defined within the scope of the function will only be visible there, unless a resulting variable is returned at the end.

Function can have 0 or more arguments/parameters (see them as options). For example setup() needs no parameters, but point() needs two (x and y).

A recursive function is essentially just a function that calls itself (usually with different parameters).

In the case of your XML, you can use a recursive function to drill down through all levels:

XML xml;

void setup(){

  xml = loadXML("data.xml");
  xml.trim();

  recursiveTraverse(xml);
}

void recursiveTraverse(XML xml){
  XML[] childNodes = xml.getChildren();
  for(int i = 0; i < childNodes.length; i++){
    println(childNodes[i].getName()+":"+childNodes[i].toString());
    if(childNodes[i].hasChildren()){
      recursiveTraverse(childNodes[i]);
    }
  }
}
George Profenza
  • 50,687
  • 19
  • 144
  • 218
  • Worked amazingly well!! Thank you so much for such a detailed response about recursive functions, you've just rocked my world! :D – max rose Sep 11 '15 at 20:28