Problems with XML traversal, trying to load XML into an array

So I am working on a tree visualization tool. I have an xml file with the data on the tree, and onload, I want that data to be loaded into an array of nodes for display. Right now I am having trouble while trying to construct new nodes for the current node's children.

Main Sketch:

//SFD Tree Visualization
//Austin Slominski 2014

Node root;
XML data;

void setup(){
  root = new Node();//initialize
  data = loadXML("nodes.xml");//initialize

  size(750,750);
  smooth(true);
  background(255);

  //NODES
    loadChild(root, data, null);
    root.display();

}

void loadChild(Node node, XML data, Node parent) {
  //loadChild looks through the XML and loads them into an array of nodes to be
  //traversed easier. Happens on load.

  //CURRENT NODE TITLE
    XML title = data.getChild("title");
    String xmlTitle = title.getContent();
    node.title = xmlTitle;

  //CURRENT NODE CHILDREN !!! TODO
    XML[] children = data.getChildren("child");
    node.children = new Node[children.length];//Construct array of new children

    //println("1");
    //node.children[1].title="test"; //FIX THIS LINE ARGHHH
    //println("2");

    //println(children.length);
    println(node.title);

    for (int i = 0; i < children.length; i++) {
      //loadChild(next, children[i], node);
      //node.children[i] = next;
      println("hi");
    }
}

void draw(){

}

void mousePressed(){
    root.clickedActive();
    root.display();
}

Node Class:

/* @pjs font="Junction-light.otf"; */
PFont f;

class Node {
  //DATA
    //Node parent;
      Node[] children;
      public String title;

    //COORDS
      int x=150;
      int y=200;
      int tWidth;
      int tHeight;
      float textSize=100;

    //ATTRIB
      int titleColor = 0;
      public boolean active = false;



  //CONSTRUCTOR
    Node(){
      f = createFont("Junction-light.otf",100,true);
      //String[] fontList = PFont.list();
      //println(fontList);
      textFont(f,textSize);  
    }
  //FUNCTIONALITY

    void display(){
      fill(titleColor);
      text(title,x,y);
      noFill();

      tHeight = textAscent();
      tWidth  = textWidth(title)+8;
      //rect(x,y-tHeight,tWidth,tHeight);//Bounding box for clicks
    }

    //CLICKED WITHIN

    void clickedActive(){
      if(mouseX > x && mouseX < x+tWidth && mouseY > y-tHeight && mouseY < y){
         if(active == true){
           active = false;
           titleColor = 0;
         }else{
           active = true;
           titleColor = 140;
         }
      }
    }

}

XML:

<?xml version="1.0" encoding="UTF-8"?>`
<root>

        <type></type>
        <title>ROOT</title>
        <description></description>
        <image></image>

        <child>
                <type></type>
                <title>Test Child 1</title>
                <description></description>
                <image></image>

                <child>
                        <type></type>
                        <title>Test Child 1b</title>
                        <description></description>
                        <image></image>
                </child>
        </child>


        <child>
                <type></type>
                <title>Test Child 2</title>
                <description></description>
                <image></image>

                <child>
                        <type></type>
                        <title>Test Child 2b</title>
                        <description></description>
                        <image></image>
                </child>
        </child>

</root>

So to sum up the problem, I am trying to create a new node for each child in the XML document, and the construction of that array is failing.

Any help would be incredibly appreciated!

Tagged:

Answers

  • line 23 in your xml is wrong (a close tag without an open), perhaps that's stopping the file from parsing.

  • (the code's small enough to post here. you'll get more answers pasting something that people can run and debug without having to faff around with pastebin)

  • edited April 2014

    Yep, caught that extra close tag a few minutes ago, I'll edit my post to help! Getting rid of that extra closing tag corrected the number of children it was finding, but still not allowing me to create those children nodes. (Main problem is line 32 of the main sketch I believe)

  • Answer ✓
    node.children = new Node[children.length];//Construct array of new children
    node.children[1].title="test"; //FIX THIS LINE ARGHHH
    

    You declare an array of Node objects, but they are null, not initialized, so node.children[1] probably throws a NullPointerException.

    See Why do I get a NullPointerException?

  • edited May 2014

    Thanks! That gets me closer. So line 1 would have to be iterated through first? In which case, would it be something like

    void loadChild(Node node, XML data, Node parent) {
      //loadChild looks through the XML and loads them into an array of nodes to be 
      //traversed easier. Happens on load.
    
      //CURRENT NODE TITLE
      XML title = data.getChild("title");
      String xmlTitle = title.getContent();
      node.title = xmlTitle;
    
      //CURRENT NODE CHILDREN
      XML[] children = data.getChildren("child");
    
    
      //node.children[1].title= xmlTitle; //FIX THIS LINE ARGHHH
    
      println(children.length);//IS CORRECT NOW
    
      for (int i = 0; i < children.length; i++) {
        node.children[i] = new Node();//Declare array of new children
        //node.children[i].title= xmlTitle;
        //loadChild(next, children[i], node);
        //node.children[i] = next;
      }
    }
    

    (Which isn't working, but am I on the right track? It is currently breaking when I include "node.children[i]", but "children[i]" alone doesn't break. Is this something related to the availability of the children array in the node class?)

  • Thanks! That gets me closer. So line 1 would have to be iterated through first? In which case, would it be something like

    node.children[i] = new Node()

    (Which isn't working, but am I on the right track?)

  • Solved (for now):

    void loadChild(Node node, XML data, Node parent) {
      //loadChild looks through the XML and loads them into an array of nodes to be 
      //traversed easier. Happens on load.
    
      //CURRENT NODE TITLE
        XML title = data.getChild("title");
        String xmlTitle = title.getContent();
        node.title = xmlTitle;
    
      //CURRENT NODE CHILDREN
        XML[] XMLchildren = data.getChildren("child");
        node.children = new Node[XMLchildren.length];//Creates new array with an index for each child
    
        for(int i=0;i<XMLchildren.length;i++){
          node.children[i] = new Node();
        }
    
        if(node.children!=null){
          println("node.children is NOT null");
        }
    
        for (int i = 0; i < XMLchildren.length; i++) {
          loadChild(node.children[i], XMLchildren[i], node);
        }
    }
    

    Is this done in a sensible way?

Sign In or Register to comment.