Problems with XML traversal

Hi everyone,

I am new to Processing and the first project I am working on is a visual representation of an xml document. Each element will be a box in the visual space, and when clicked, it generates boxes for each of that nodes children. So far I have played with the XML documentation on the site, but I can't seem to get what I need from them. Currently, this is my XML document:

<?xml version="1.0"?>
<root>
  <child>
      <subchild id="0">
        <item1>
            Item 1 Content
        </item1>
        <item2>
            Item 2 Content
        </item2>
        <item3>
            Item 3 Content
        </item3>
      </subchild>
      <subchild id="1">
        <item1>
            Item 1 Content
        </item1>
        <item2>
            Item 2 Content
        </item2>
        <item3>
            Item 3 Content
        </item3>
      </subchild>
      <subchild id="2">
        <item1>
            Item 1 Content
        </item1>
        <item2>
            Item 2 Content
        </item2>
        <item3>
            Item 3 Content
        </item3>
      </subchild>
  </child>
</root>

My goal is to have a Node object, and in it, it can start at the root and create new objects for each children and so on. I am running into problems even getting the child elements to show up properly. Does anyone have tips, similar patches, or resources that I can use for XML in Processing 2?

Thanks, Austin

Tagged:

Answers

  • You posted in Questions about Code, so you should show your code, so we can find out what you did wrong, and fix it.

  • Here is the first tab:

    XML xml;
    Node s;
    
    void setup(){
      //CANVAS SETTINGS
      size(500, 500);
    
      //INITIATE OBJECTS
      xml = loadXML("modernism.xml");
      s = new Node();
    }
    
    void draw(){
      background(255);
    
      s.displayText();
      s.displayBox();
      s.overBox();//checks to see if box is hovered over
    
    }
    
    void mouseClicked(){
      s.clicked();
      //if(s.activeCheck()){
    
      //}
    }
    

    and the second:

    //Builds nodes for content. User can click on nodes
    //and the nodes will expand to display children.
    //Incorporate XML
    
    class Node {
    
      //DATA
    
      //XML
      XML firstChild;
      XML[] children;
    
      //APPEARANCE
      color textColor;
      color boxColor;
      float xpos = width/2;
      float ypos = 100;
      float nodeWidth;
      float nodeHeight;
      boolean overBox = false;
      boolean active = false;
      PFont font;
    
    
    
      //CONSTRUCTOR
      Node(){
    
        //XML
        firstChild = xml.getChild("child");
        children = xml.getChildren("root");//will generate array of all children
    
        //APPEARANCE
        textColor = color(0);//sets text color
        boxColor = color(244);//sets box color
        font = createFont("Gil Sans", 16, true);
        textFont(font,50);
        nodeWidth = textWidth("filler");//INPUT TEXT
        nodeHeight = textAscent();//?textDescent()?
        rectMode(RADIUS);
    
        //DEBUG
        println(firstChild);
        printArray(children);
      }
    
      void displayText(){
        fill(textColor);
        text("filler",xpos-nodeWidth/2,ypos+nodeHeight/2.3);
      }
    
      void displayBox(){
        //stroke(boxColor);
        noStroke();
        noFill();
        rect(xpos, ypos, nodeWidth/2, nodeHeight/2);
    
        //FOR DEBUGGING OVERBOX
        //stroke(135);
        //point(300,200);
      }
    
      void overBox(){
        if(mouseX > xpos-nodeWidth/2 && mouseX < xpos+nodeWidth/2 &&
           mouseY > ypos-nodeHeight/2 && mouseY < ypos+nodeHeight/2) {
          overBox = true;  
        }else{
          overBox = false;
        }
      }
    
       void clicked(){
    
         if(active) {
         //If box was already clicked, trigger response
           if(overBox){
             textColor = color(0);
             overBox = false;
             active = false;
           }
         }
    
         if(overBox) {
         //checks to see if click happened within bounds of box, makes active
           textColor = color(100);
           active = true;
         }
       }
    
       private void connector(){
    
       }
    
        boolean activeCheck(){
          if(active == true){
           return true;
          }else{
           return false; 
          }
        }
    } 
    

    I just didn't include it in the first post because it is very rough and I have torn it apart trying to get the XML to work.

  • edited February 2014

    this reads a text-file

    it needs a csv file in the data folder - see below

    maybe it helps...

    /* in the data folder 
    
     file outgoing.csv
    
     Parent, Child 1
     Parent, Child 2
     Parent, Child Paul
     Parent 2, Something
    
    
     */
    //
    ArrayList<Item> items;
    ArrayList<GraphicalItem> graphicalItems; 
    //
    final color lightGreen = color (2, 244, 2, 22);
    final color lightBlue = color(2, 0, 244, 22);
    //
    // State of programs
    final int stateNormal = 0; 
    final int stateGraphical = 1;
    final int stateTextual = 2;
    int state=stateNormal;
    //
    // paths 
    // Editor program 
    final String strEditor = "notepad.exe";
    // data
    final String stringchildrenCsv = "outgoing.csv";
    //
    int intClassCounter=0;
    int itemChosen=-1;
    //
    // for graphical  
    float myScale = 1.0;      // for scale and translating 
    float myTranslate = 0.0;
    int lineY = 40;        // where to place net box vertically
    boolean hold=false;    // mouse dragged? 
    GraphicalItem holdItem ;  // which item is dragged 
    //
    
    // ---------------------------------------------------------------
    void setup() {
      size( displayWidth, displayHeight );
      smooth();
      noStroke();
      fill(0);
      println("Start");
      //
      // 
      //load 
      String list[] = loadStrings(stringchildrenCsv);
      println("There are " + list.length 
        + " lines for children.");
      //
      // Create an empty ArrayList
      items = new ArrayList();
      //
      // 
      // load data in the ArrayList
      // outgoing
      for (int i = 0; i <= list.length-1; i++ ) {  
        if (!list[i].equals("")) {
          String[] thisLine=split (list[i], ",");
          int currentElement; 
          // eval lines element #0 = parent/item 
          thisLine[0] = thisLine[0].trim();
          // if new
          if (!isInArraylist (thisLine[0], items)) {
            items.add(new Item(thisLine[0], intClassCounter));
            currentElement= intClassCounter;
            intClassCounter++;
          }
          else 
          {
            currentElement = whereInArraylist (thisLine[0], items )  ;
          }
          // eval lines element #1 and following 
          for (int iItem = 1; iItem <= thisLine.length-1; iItem++ ) {  
            thisLine[iItem] = thisLine[iItem].trim();
            if (!thisLine[iItem].equals("")) {
              Item item1 = items.get(currentElement);
              item1.addchildren ( thisLine[iItem] ) ;
            }
          }
        }
      } 
    
      // ------------------------------------------
      //
      // Create an empty ArrayList
      graphicalItems = new ArrayList();
      //
      holdItem = new GraphicalItem( 0, 0, 
      "Dummy", "Dummy", 
      -1, -1, -1, -1, 
      lightBlue);
      //
      myScale     = 1.0; // reset 
      myTranslate = 0.0;
      initGraphical();
      state=stateGraphical;
    } // func 
    // 
    // 
    void draw() {
      background(255);
      //
      if (state==stateNormal) {
        if  (itemChosen<0) {
          mainMenu();
        }
        else
        {
          showItem ();
        } // if
      }
      else if (state==stateTextual) {
        showTextual();
      }
      else if (state==stateGraphical) {
        scale(myScale);
        translate( 0, myTranslate ) ;     
        showGraphical();
      }
      else {
        println ("Error 182" );
      }
    } // func
    //
    // --------------------------------------------------------------------
    //
    void mainMenu() {
      text ( "List of the items. ", 20, 20 );
      // With an array, we say items.length, with an ArrayList, we say items.size()
      // The length of an ArrayList is dynamic
      for (int i = 0; i <= items.size()-1; i++ ) {
        // ArrayList
        Item item1 = items.get(i);
        item1.display(  i, 20, i*20+50  );
      }
      text ( "Please enter the item you want to see (0-9, afterwards return to come back here).", 
      20, items.size() *20+60  );
      text ( "Or use: o load outgoing; t textual, g graphical.", 
      20, items.size() *20+80  );
    } // func 
    //
    // -------------------------------------------
    // 
    void showItem () {
      // shows one item as text children 
      if (itemChosen < items.size() ) {
        // show item
        Item item1 = items.get(itemChosen);
        text ( "You chose:  " 
          + item1.name, 20, 20  );
    
        // children
        String result = "";
        stroke(209);
        line(20, 225, 220, 225);
        text("children : ", 20, 240 );      
        result = item1.getchildren( 0 );
        if (trim(result).equals("")) {
          fill(244, 2, 2);
          text("Nothing. Error: No children. ", 20, 260);
          fill(0);
        }
        else {
          text(result, 20, 260);
        }    
        text("Return to continue", 20, height-20);
      }
      else {
        text("This item doesn't exist yet", 20, 60);
        text("Return to continue", 20, 90);
      }
    } // func 
    //
    // -------------------------------------------------------------------------
    //
    // 
    // Inputs ****************************************************
    // 
    void mousePressed() {
      if (state==stateGraphical) {
        if (mouseButton==LEFT) {
          for (int i = 0; i <= graphicalItems.size()-1; i++ ) { 
            GraphicalItem myGraphicalItem1 = graphicalItems.get(i);
            if (myGraphicalItem1.isMouseOver()) {
              // return myGraphicalItem1;
              println(true);
              hold=true;
              holdItem=myGraphicalItem1;
            }
          } // for
        } // if
      } // if
    } // func 
    //
    void mouseDragged() {
      if (state==stateGraphical) {
        if (hold) {
          holdItem.Position.x = mouseX; 
          holdItem.Position.y = mouseY;
        }
        if (mousePressed && mouseButton == RIGHT) {
          myScale=(map(mouseX, 0, width, 0, 2));  
          myTranslate =  map(mouseY, 0, height, -height, height) ;
        } // if
      } // if
    } // func 
    // 
    void mouseReleased () {
      if (state==stateGraphical) {
        if (mouseButton == LEFT) {
          hold = false;
        }
      }
    }
    //
    void keyPressed () {
      if (state==stateNormal) {
        keyPressedStateNormal();
      }
      else if (state==stateGraphical) {
        //keyPressedStateGraphical
        if (key == RETURN || key == ENTER) {
          // return to main menu
          state=stateNormal;
          // un-choose item, return to main menu
          itemChosen = -1;
          // println("main menu");
        }
      }
      else if (state==stateTextual) {
        if (key == RETURN || key == ENTER) {
          // return to main menu
          state=stateNormal;
          // un-choose item, return to main menu
          itemChosen = -1;
          // println("main menu");
        }
      }
      else {
        println("Error 429");
      }
    } // keyPressed
    
    void keyPressedStateNormal() {
      // key
      if (key >= '0' && key <= '9') {
        // when item is not chosen
        if (itemChosen < 0) {
          // take the ascii and make it 0..9
          // choose item
          itemChosen = int(key)-48;
        } // if
      }
      else if (key == RETURN || key == ENTER) {
        // reset
        // println("return");
        // when item is chosen
        if (itemChosen > -1) {
          // un-choose item, return to main menu
          itemChosen = -1;
        }
      }
      else if (key == 'n') {
        //
      }
      else if (key == 'o') {
        //
        // open outgoing 
        open( strEditor
          + " "
          + dataPath("") 
          + stringchildrenCsv );
      }
      else if (key == 'g') {
        // go graphical
        myScale     = 1.0; // reset 
        myTranslate = 0.0;
        initGraphical();
        state=stateGraphical;
      }
      else if (key == 't') {  
        state=stateTextual;
      }
      else {
        // do nothing
      } // else
    }
    //
    // =================================================================
    //
    void initGraphical() {
      // only fills the graphicalItems from the arrayList
      graphicalItems.clear();
      lineY = 40;
      //
      // loop over all items 
      for (int i = 0; i <= items.size()-1; i++ ) {
        // get it from ArrayList 
        Item item1 = items.get(i);
    
        graphicalItems.add ( new GraphicalItem( 20, lineY, 
        "Parent", item1.name, 
        -1, -1, -1, -1, 
        lightGreen ));
    
        // now show outgoing Proficiencies and from there 
        // all Proficiencies and items.
        // Recursive 
        showchildren( item1, graphicalItems.size()-1, 0 );
    
        lineY+=160;
        // } // if
      } // for
    } // func 
    //
    //
    void showchildren(Item class1, int myPointerToClass, int depth) {
      // only fills the graphicalItems from the arrayList
      // with children - recursive.
      // Since it's recursive we need a depth.
      int myPointer=0;
      // loop through children of class1
      for (int j = 0; j < class1.countchildren; j++) {
        // try get the child
        GraphicalItem theProficiencyGraphic =
          getElement("Child", class1.children[j]);
        // Is it new? 
        if (theProficiencyGraphic == null) {          
          graphicalItems.add ( new GraphicalItem( (depth+1)*290-120, lineY, 
          "Child", class1.children[j], 
          -1, -1, -1, myPointerToClass, 
          lightBlue));
          myPointer = graphicalItems.size()-1; 
          lineY+=77;
        } 
        else {
          // not new 
          // add new line at "theProficiencyGraphic"
          int intNumber = getElementNumber("Child", class1.children[j]);
          if (intNumber!=-1) {
            theProficiencyGraphic.addAdaptor ( -1, -1, -1, myPointerToClass );
            myPointer = intNumber;
            lineY-=77;
          }
        }
        int myPointerToClass2=-1;
        // now search items that have those outgoing proficiencies as needed
        for (int k = 0; k <= items.size()-1; k++ ) {
          // class to test
          Item class2 = items.get(k);
        } // for
      } // for
    } // func
    //
    void showGraphical() {
      // only shows the graphicalItems from the arrayList
      text ( "Graphical Representation  "
        + "                  "
        + "Return to continue. Drag with right mouse button: scale (x-direction) and up/down (y-direction)", 20, 14 );
      for (int i = 0; i <= graphicalItems.size()-1; i++ ) { 
        GraphicalItem myGraphicalItem1 = graphicalItems.get(i);
        myGraphicalItem1.display() ;
      } // for
    } // func 
    //
    GraphicalItem getElement( String textHeaderParam, String textNormalParam ) {
      // returns object or null
      for (int i = 0; i <= graphicalItems.size()-1; i++ ) { 
        GraphicalItem myGraphicalItem1 = graphicalItems.get(i);
        if (myGraphicalItem1.textHeader.equals(textHeaderParam) && 
          myGraphicalItem1.textNormal.equals(textNormalParam)) {
          return myGraphicalItem1;
        } // if
      } // for
      return null;
    } // func 
    //
    int getElementNumber( String textHeaderParam, String textNormalParam ) {
    
      // returns object or null
      for (int i = 0; i <= graphicalItems.size()-1; i++ ) { 
        GraphicalItem myGraphicalItem1 = graphicalItems.get(i);
        if (myGraphicalItem1.textHeader.equals(textHeaderParam) && 
          myGraphicalItem1.textNormal.equals(textNormalParam)) {
          return i;
        } // if
      } // for 
    
      return -1;
    } // func 
    //
    // =====================================================================
    // minor tools *******************************
    boolean isInArraylist (String thisLine, ArrayList ArraylistTest) {
      // checks if thisLine is in the ArrayList 
      for (int i = 0; i <= items.size()-1; i++ ) {
        // ArrayList 
        Item class1 = items.get(i);
        if (class1.name.equals( thisLine)) {
          return true;
        }
      }
      return false;
    }
    //
    int whereInArraylist (String thisLine, ArrayList ArraylistTest) {
      // assumes thisLine is in the ArrayList and returns the pos
      for (int i = 0; i <= items.size()-1; i++ ) {
        // ArrayList 
        Item class1 = items.get(i);
        if (class1.name.equals( thisLine)) {
          return i;
        }
      }
      return -1;
    }
    //
    String whichClassHasAschildren (String testing) {
      // checks which class(es) has / have the outgoing "testing"
      final String bufferInitial="provided by "; 
      String buffer=bufferInitial;
      //
      for (int i = 0; i <= items.size()-1; i++ ) {
        // ArrayList 
        Item class1 = items.get(i);
        if (class1.doesHavechildren(testing)) {
          buffer+=class1.name+ ", ";
        }
      }
      buffer = buffer.trim();
      if (buffer.charAt(buffer.length()-1)==',') {
        buffer=buffer.substring(0, buffer.length()-1);
      }
      buffer=buffer.trim();
      if (buffer.trim().equals(trim(bufferInitial))) {
        buffer = "Error: No class provides this.";
        // println("Error");
      }
      return buffer;
    }
    //
    void showTextual() {
      // 
      text ("Textual Representation (items and outgoing)", 20, 14 );
      int lineY = 40;
      for (int i = 0; i <= items.size()-1; i++ ) {
        // ArrayList 
        Item class1 = items.get(i);
        class1.display(  i, 20, lineY );
        lineY+=17; 
        // give back String
        String buffer="";
        for (int j = 0; j < class1.countchildren; j++) {
          buffer=buffer +  class1.children[j]  + "\n";
          text (class1.children[j], 49, lineY ); 
          lineY+=17;
        } // for
        lineY+=9;
      } //
      text("Return to continue", 20, height-40);
    } // func 
    
    //
    // ===========================================================
    // classes 
    //
    class Item {
      String name;
      int index;
      //
      // children
      String[] children = new String[32];  //  array
      //
      int countchildren ;
      //
      //
      // constructor
      Item(String tempClassName, int tempIndex) {
        name = tempClassName;
        index=tempIndex;
        countchildren = 0;
      }  // constructor
      //
      void display( int i, int x, int y) {
        // display
        fill(0);
        text(index
          + ". "
          + name, 
        x, y);
      } // method
      //
      //
      void addchildren (String s ) {
        // within the class is an array
        // here you put something in it
        children[ countchildren ] = s;
        countchildren++;
      } // method
      //
      //
      String getchildren( int depth) {
        // give back String
        String buffer="";
        for (int i = 0; i < countchildren; i++) {
          buffer=buffer +  children[i]  + "\n";
        } // for
        return buffer;
      } // method
      //
      // does have methods 
      //
      boolean doesHavechildren(String testing) {
        // checks if the class has the outgoing "testing"
        for (int i = 0; i < countchildren; i++) {
          if (children[i].equals(testing) ) {
            return true;
          } // if
        }  // for 
        return false;
      } // method  
      //
    } // class
    
    // ==============================================================
    
    class GraphicalItem {
      //
      PVector Position;   // Pos and size of the whole box
      PVector boxSize;    // Size 
      final int headerHeight = 20;  // Height of header text
      color headerColor; 
      //
      String textHeader="";
      String textNormal="";
      //
      PVector adaptorLeft, adaptorRight;  // Positions of adaptors
      PVector adaptorUp, adaptorDown;  
      //
      // where the adaptors lead to: array of 
      // Indices of another GraphicalItem
      int adaptorUpTo[]     = new int [1]  ;  
      int adaptorRightTo[]  = new int [1]  ;  
      int adaptorDownTo[]   = new int [1]  ;  
      int adaptorLeftTo[]   = new int [1]  ;  
      //
      // constructor ---------------------------------------------------
      GraphicalItem(int _x, int _y, 
      String _header, String _normalText, 
      int _adaptorUpTo, int _adaptorRightTo, 
      int _adaptorDownTo, int _adaptorLeftTo, 
      color _tempColor) {
        // constructor
        Position = new PVector();
        boxSize = new PVector( 100, 70 );
        Position.x=_x;
        Position.y=_y;
        //
        textHeader=_header;
        textNormal=_normalText;
        //
        adaptorUpTo [0]   = _adaptorUpTo;
        adaptorRightTo[0] = _adaptorRightTo;
        adaptorDownTo [0] = _adaptorDownTo;
        adaptorLeftTo [0] = _adaptorLeftTo;
        //
        adaptorLeft = new PVector( 0, boxSize.y/2 );
        adaptorRight = new PVector( boxSize.x, boxSize.y/2 );    
        adaptorUp = new PVector( boxSize.x/2, 0 );
        adaptorDown  = new PVector( boxSize.x/2, boxSize.y );
        //
        headerColor = _tempColor;
      }// constructor
      //
      void display() {
        fill (headerColor);
        stroke(0);
        // header rect
        rect (Position.x, Position.y, 
        boxSize.x, headerHeight);
        fill(244);
        // rect for normal text field (lower half)
        rect (Position.x, Position.y+headerHeight, 
        boxSize.x, boxSize.y-headerHeight);    
        // horizontal line between header text and normal text
        // text  
        fill (0);
        text (textHeader, Position.x+4, Position.y+2, boxSize.x-5, headerHeight);
        text (textNormal, Position.x+4, Position.y+headerHeight+2, boxSize.x-5, boxSize.y-headerHeight);
        // adaptors
        GraphicalItem myGraphicalItem1;
        for (int i=0; i < adaptorLeftTo.length; i++) {
          if (adaptorLeftTo[i]>-1) {
            myGraphicalItem1 = graphicalItems.get( adaptorLeftTo[i] );
            line (Position.x+adaptorLeft.x, 
            Position.y+adaptorLeft.y, 
            myGraphicalItem1.Position.x + myGraphicalItem1.adaptorRight.x, 
            myGraphicalItem1.Position.y + myGraphicalItem1.adaptorRight.y);
          }
        }
      } // method 
      //
      void addAdaptor(  
      int _adaptorUpTo, int _adaptorRightTo, 
      int _adaptorDownTo, int _adaptorLeftTo) {
        // 
        if (_adaptorLeftTo>-1) {
          adaptorLeftTo=append(adaptorLeftTo, _adaptorLeftTo );
        }
      } // method 
      //
      boolean isMouseOver() {
        if (mouseX>Position.x && mouseX<Position.x+boxSize.x && 
          mouseY>Position.y && mouseY<Position.y+boxSize.y) {
          return true;
        } 
        else 
        {
          return false;
        }
      } // method
    } // class 
    // ==============================================================
    
  • You can specify which kind of children you want in getChildren(), like getChildren("child") or getChildren("item").

    This allows to get more precise information.

  • edited March 2014

    ok, I modified your xml file:

  • edited March 2014

    ok, I modified your xml file:

  • edited March 2014

    ok, I modified your xml file:

  • wanted to post the new xml-file but were not possible (xml) but then the forum gave me 600 seconds block (because I was suspect of spamming)........ argh....

  • edited March 2014

    anyway it posted my message despite the error message

    here is the new code - based on your code

    XML xml;
    Node s;
    
    void setup() {
      //CANVAS SETTINGS
      size(500, 500);
    
      //INITIATE OBJECTS
      xml = loadXML("modernism.xml");
      s = new Node();
    
      println("-------------------------");
    
      XML[] children = xml.getChildren("child");
    
      for (int i = 0; i < children.length; i++) {
    
        XML[] children2 = children[i].getChildren("subchild");
    
        println ("Found "+children2.length+" subchildren    ++++++++++");
    
        for (int i2 = 0; i2 < children2.length; i2++) {
    
    
          int id = children2[i2].getInt("id");
    
          // String coloring = children[i].getString("species");
          String name = children2[i2].getContent();
    
          println("count attribs " + children2[i2].getAttributeCount());
    
          println(id + ", " +  ", " + name);
        } // for
      } // for
    
      println("-------------------------");
    } // setup 
    
    void draw() {
      background(255);
    
      s.displayText();
      s.displayBox();
      s.overBox();//checks to see if box is hovered over
    }
    
    void mouseClicked() {
      s.clicked();
      //if(s.activeCheck()){
    
      //}
    }
    
    // and the second:
    
    
    
    
    //Builds nodes for content. User can click on nodes
    //and the nodes will expand to display children.
    //Incorporate XML
    
    class Node {
    
      //DATA
    
      //XML
      XML firstChild;
      XML[] children;
    
      //APPEARANCE
      color textColor;
      color boxColor;
      float xpos = width/2-100;
      float ypos = 100;
      float nodeWidth;
      float   nodeHeight;
      boolean overBox = false;
      boolean active = false;
      PFont   font;
    
    
    
      //CONSTRUCTOR
      Node() {
    
        //XML
        firstChild = xml.getChild("child");
        children = firstChild.getChildren("subchild");//will generate array of all children
        println("##################");
        println (children);
        //APPEARANCE
        textColor = color(0);//sets text color
        boxColor = color(244);//sets box color
        font = createFont("Gil Sans", 16, true);
        textFont(font, 50);
        nodeWidth = textWidth("filler");//INPUT TEXT
        nodeHeight = textAscent();//?textDescent()?
        rectMode(RADIUS);
    
        //DEBUG
        println(firstChild);
        printArray(children);
      }
    
      void displayText() {
        fill(textColor);
        text("filler", xpos-nodeWidth/2, ypos+nodeHeight/2.3);
      }
    
      void displayBox() {
        //stroke(boxColor);
        // noStroke();
        stroke(11);
        noFill();
        rect(xpos, ypos, nodeWidth/2, nodeHeight/2);
    
        if (active) {
    
          fill(11);
          int lineY = 20;   
          textSize(11);
          for (int i2 = 0; i2 < children.length; i2++) {
    
            int id = children[i2].getInt("id");
    
            // String coloring = children[i].getString("species");
            String name = children[i2].getContent();
    
            name = name.trim();
            name.trim();
            // println (name);
            name=name.replace(char(10), ' ');
            name = name.trim();
            name.trim();
    
            text( "subchild "+i2 +": "+name, xpos+60, ypos+lineY);
    
            // println("count attribs " + children2[i2].getAttributeCount());
    
            // println(id + ", " +  ", " + name);
            lineY+=65;
          } // for
          textSize(50);
        } //  if 
    
        //FOR DEBUGGING OVERBOX
        //stroke(135);
        //point(300,200);
      }
    
      void overBox() {
        if (mouseX > xpos-nodeWidth/2 && mouseX < xpos+nodeWidth/2 &&
          mouseY > ypos-nodeHeight/2 && mouseY < ypos+nodeHeight/2) {
          overBox = true;
        }
        else {
          overBox = false;
        }
      }
    
      void clicked() {
    
        if (active) {
          //If box was already clicked, trigger response
          if (overBox) {
            textColor = color(0);
            overBox = false;
            active = false;
          }
        }
    
        if (overBox) {
          //checks to see if click happened within bounds of box, makes active
          textColor = color(100);
          active = true;
        } // if
      } // method 
    
      private void connector() {
      }
    
      boolean activeCheck() {
        if (active == true) {
          return true;
        }
        else {
          return false;
        }
      }
    } 
    
  • but I don't feel the approach is correct

    because when one subchild had a child, we coudn't display it

    also when it had a child we want that also to be a node (so with frame and expendable)

    So maybe we have to have an arraylist of nodes and each node knows what children (and parent) it has

    That would make the class Node very slim / lean

  • the error message now always shows up in this thread but he posts anyway - just hit F5

  • Good luck!

  • edited March 2014

    here is what I meant - a Node is only one item

    final int UNDEFINED = -1;
    ArrayList<Node> nodes = new ArrayList();
    
    void setup() {
      //CANVAS SETTINGS
      size(500, 900);
    
      // xml class 
      XML xml;
    
      //INITIATE OBJECTS
      xml = loadXML("modernism.xml");
    
      println("-------------------------");
    
      XML[] children = xml.getChildren();
    
      // println(xml.listChildren());
      println(children.length);
    
      int indexArrayList = 0;
      int currentParentIndexArrayList = -1; 
    
      // the outer for-loop 
      for (int i = 0; i < children.length; i++) {
    
    
        println(children[i].getName());
    
        if (!children[i].getName().equals("#text")) {
    
          nodes.add ( new Node ( indexArrayList, children[i].getName(), UNDEFINED, 0, UNDEFINED, "" ) );
          currentParentIndexArrayList = indexArrayList;  
          indexArrayList++;
    
          XML[] children2 = children[i].getChildren("subchild");
    
          println ("Found "+children2.length+" subchildren    ++++++++++");
    
          // the inner for-loop 
          for (int i2 = 0; i2 < children2.length; i2++) {
            int    id         = children2[i2].getInt("id");
            String strContent = children2[i2].getContent();
            println("count attribs " + children2[i2].getAttributeCount());
            nodes.add  ( new Node ( indexArrayList, "subchild "+i2, currentParentIndexArrayList, 1, id, strContent ) );
            int currentParentIndexArrayList2=indexArrayList;
            indexArrayList++;
            println(id + ", " + strContent);
    
            XML[] children3 = children2[i2].getChildren();
            for (int i3 = 0; i3 < children3.length; i3++) {
              if (!children3[i3].getName().equals("#text")) {
                nodes.add  ( new Node ( indexArrayList, children3[i3].getName(), currentParentIndexArrayList2, 2, 3, "Hi" ) );
                indexArrayList++;
              } // if 
              //
            } // for
          } // for
          //
        } // if
      } // for
    
      println("end of setup() -------------------------");
    } // setup 
    
    void draw() {
      background(255);
      for ( Node s : nodes ) {
        if (s.visible) {
          s.displayText();
          s.displayBox();
        } // if 
        s.overBox();     //checks to see if box is hovered over
      } // for
    } // func 
    
    void mouseClicked() {
      for ( Node s : nodes ) {
        // func checks and sets property overBox
        s.overBox(); //checks to see if box is hovered over
        // check property 
        if (s.overBox) { 
          s.clicked();
          //if(s.activeCheck()){
        } // if
      } // for
    } // func 
    
    // ======================================================================
    
    // Builds nodes for content. User can click on nodes
    // and the nodes will expand to display children.
    
    class Node {
    
      //APPEARANCE
      color textColor;
      color boxColor;
      float xpos = 0;
      float ypos = 0;
      float nodeWidth;
      float nodeHeight;
      boolean overBox = false;
      boolean active = true;
      PFont   font;
    
      boolean visible = true; 
    
      String name = ""; 
      int id = 0;
      int id_Parent = 0;
      int depth ;
    
      int permanentID = UNDEFINED;
      String content = "";
    
      boolean hasChild=false;
    
      //  //CONSTRUCTOR I
      //  Node() {
      //
      //    //XML
      //    //    firstChild = xml.getChild("child");
      //    //    children = firstChild.getChildren("subchild");//will generate array of all children
      //    println("##################");
      //    //println (children);
      //    //APPEARANCE
      //    textColor = color(0);//sets text color
      //    boxColor = color(244);//sets box color
      //    font = createFont("Gil Sans", 16, true);
      //    textFont(font, 50);
      //    nodeWidth = textWidth("filler");//INPUT TEXT
      //    nodeHeight = textAscent();//?textDescent()?
      //    rectMode(RADIUS);
      //
      //    //DEBUG
      //    //    println(firstChild);
      //    //    printArray(children);
      //  }
    
      //CONSTRUCTOR II
      Node( int id, String name, int id_Parent, int depth, int permanentID, String content  ) {
    
        this.name        = name;
        this.id          = id;
        this.id_Parent   = id_Parent;
        this.depth       = depth;
        this.permanentID = permanentID;
        this.content     = content;
    
        xpos = width/2-100 + 30 * depth;
        ypos = 40 + 30 * id; 
    
        if (id_Parent!=UNDEFINED) {
          nodes.get(id_Parent).hasChild=true;
        } // if  
    
        //APPEARANCE
        textColor = color(0);//sets text color
        boxColor = color(244);//sets box color
        font = createFont("Gil Sans", 16, true);
        textFont(font, 50);
        nodeWidth = textWidth("filler");//INPUT TEXT
        nodeHeight = 20; // textAscent();//?textDescent()?
        rectMode(RADIUS);
      } // constr II 
    
      void displayText() {
        fill(textColor);
        textSize(11);
        textAlign(CENTER, CENTER);
        text(name, xpos, ypos);
      }
    
      void displayBox() {
        stroke(11);
        noFill();
        rect(xpos, ypos, nodeWidth/2, nodeHeight/2);
    
        if (active) {
          fill(11);
          int lineY = 20;   
          textSize(11);
          textSize(50);
        } //  if 
        else {
          // do nothing
        } // else 
        //
        // draw a line to parent if it has one
        if (id_Parent != UNDEFINED) {
          line (xpos-nodeWidth/2, ypos, 
          nodes.get(id_Parent).xpos-nodeWidth/2, nodes.get(id_Parent).ypos + nodeHeight/2);
        }
        //
        // draw plus sign + if it has child
        if (hasChild) {
          textSize(11);
          text("+", xpos-nodeWidth/2+6, ypos);
        } // if
      } // method 
    
      void overBox() {
        if (mouseX > xpos-nodeWidth/2 && mouseX < xpos+nodeWidth/2 &&
          mouseY > ypos-nodeHeight/2 && mouseY < ypos+nodeHeight/2) {
          overBox = true;
          // when data not empty
          if (visible && (permanentID!=UNDEFINED || !content.equals(""))) {
            // yellow text box 
            textSize(11);
            fill(244, 200, 32);
            stroke(0);
            // println(ypos+nodeHeight);
            rect( xpos+nodeWidth+40, ypos+nodeHeight, 50, 100);
            fill(0);
            text (permanentID+":"+content, xpos+nodeWidth+40, ypos+nodeHeight);
          }
        }
        else {
          overBox = false;
        }
      }
    
      void clicked() {
        if (active) {
          //If box was already clicked, trigger response
          if (overBox) {
            textColor = color(0);
            overBox = false;
            active = false;
            // hide children
            for (Node n : nodes) {
              if (n.id_Parent==id) {
                n.visible=false;
              }
            } // for
    
            // hide childrens children (hide child when parent is not visible) 
            for (Node n : nodes) {
              if (n.id_Parent!=UNDEFINED) {
                if (!nodes.get(n.id_Parent).visible) {
                  n.visible=false;
                } // if
              } // if
            } // for
            //
          } // if
        }
    
        if (overBox) {
          //checks to see if click happened within bounds of box, makes active
          textColor = color(100);
          active = true;
          // show children
          for (Node n : nodes) {
            if (n.id_Parent==id) {
              n.visible=true;
    
              // show childrens children
              for (Node n2 : nodes) {
                if (n2.id_Parent!=UNDEFINED) {
                  // when parents id == id we just made visible
                  // we have a child (and make it visible too)
                  if (n2.id_Parent == n.id) {
                    n2.visible=true;
                  } // if
                } // if
              } // for
            }
          } // for
        } // if
      } // method 
    
      //  private void connector() {
      //  }
    
      boolean activeCheck() {
        if (active == true) {
          return true;
        }
        else {
          return false;
        }
      }
    } 
    //
    
  • Answer ✓
    some text
    <?xml version="1.0"?>
    
    <root>
    
    
    <child>
    
    
    <subchild id="0">
    
    <item1> Item 1 Content </item1>
    
    <item2> Item 2 Content </item2>
    
    <item3> Item 3 Content </item3>
    
    </subchild>
    
    
    <subchild id="1">
    
    <item1> Item 1 Content </item1>
    
    <item2> Item 2 Content </item2>
    
    <item3> Item 3 Content </item3>
    
    </subchild>
    
    
    <subchild id="2">
    
    <item1> Item 1 Content </item1>
    
    <item2> Item 2 Content </item2>
    
    <item3> Item 3 Content </item3>
    
    </subchild>
    
    </child>
    
    
    <child2>
    
    
    <subchild id="0">
    
    <item1> Item 1 w2</item1>
    
    <item2> Item 2 w22</item2>
    
    <item3> Item 3 w3</item3>
    
    </subchild>
    
    
    <subchild id="1">
    
    <item1> Item 1 d33</item1>
    
    <item2> Item 2 d334</item2>
    
    <item3> Item 3 d6667</item3>
    
    </subchild>
    
    
    <subchild id="2">
    
    <item1> Item 1 dc</item1>
    
    <item2> Item 2 dx</item2>
    
    <item3> Item 3 dk</item3>
    
    </subchild>
    
    </child2>
    
    
    </root>
    
    some text 
    
  • I'll start pulling this apart and try it out! Sorry for the delayed response!

Sign In or Register to comment.