Loading...
Logo
Processing Forum
Hello,

Using XMLElement I would like to find the number of times that "zombie" appears in the <state> tag (see example code below).

I can use .getChildCount() to find how many children there are overall, so it seems like there'd be some way to add a simple selector so that it only pulled the children I specify. I've played around with the other .get operators and I haven't gotten any results. Thoughts?

<players>
        <name id="1">Brian.Klingenfus</name>
        <state>human</state>
        <kills>0</kills>
        <fed>2010-11-09 23:45:33</fed>
        <name  id="2">Allyson.Johnson ?</name>
        <state>human</state>
        <kills>0</kills>
        <fed>2010-11-09 23:47:06</fed>
        <name id="3">Justin.Clatterbuck ?</name>
        <state>human</state>
        <kills>0</kills>
        <fed>2010-09-20 00:32:00</fed>
     <name id="9">Debel Issttas</name>
        <state>zombie</state>
        <kills>1</kills>
        <fed>2010-09-17 04:02:00</fed>
        <name id="10">Stad Angtia</name>
        <state>zombie</state>
        <kills>2</kills>
        <fed>2010-09-18 12:00:00</fed>
        <name id="11">Ashet Enild</name>
        <state>zombie</state>
        <kills>0</kills>
        <fed>2010-11-09 23:45:33</fed>
        <name id="12">Sokel Ildup</name>
        <state>zombie</state>
        <kills>2</kills>
        <fed>2010-11-09 23:47:06</fed>
        <name id="13">Dyum Atub</name>
        <state>zombie</state>
        <kills>0</kills>
        <fed>2010-09-20 00:32:00</fed>
        <name id="14">Serild Phiser</name>
        <state>zombie</state>
        <kills>1</kills>
        <fed>2010-09-19 18:49:33</fed>
        <name id="15">Turoldi Osbald</name>
        <state>zombie</state>
        <kills>1</kills>
        <fed>2010-09-18 21:35:44</fed>
        <name id="16">Sumos Pervesi</name>
        <state>zombie</state>
        <kills>1</kills>
        <fed>2010-09-17 16:18:46</fed>
        <name id="17">Yerrotho Rispola</name>
        <state>zombie</state>
        <kills>3</kills>
        <fed>2010-09-17 04:02:00</fed>
        <name id="18">Quevhon Turdra</name>
        <state>zombie</state>
        <kills>0</kills>
        <fed>2010-09-18 12:00:00</fed>
     <name id="19">Ineagea Enhund</name>
        <state>zombie</state>
        <kills>0</kills>
        <fed>2010-09-17 04:02:00</fed>
        <name id="20">Vukim Iroughi</name>
        <state>zombie</state>
        <kills>0</kills>
        <fed>2010-09-18 12:00:00</fed>
</players>


Here is my current processing code:




void setup() {
  size(200, 200);
  XMLElement xml;
  xml = new XMLElement(this, "table.xml");
  int numPlayers = xml.getChildCount();
  int numZombies = xml.getChildCount(zombie);
  for (int i = 0; i < numPlayers; i++) {
    XMLElement kid = xml.getChild(i);
    int id = kid.getIntAttribute("id"); 
    String name = kid.getContent();
    String state = kid.getContent();
  }


void draw(){
  float players = numPlayers/4;
float zombies = 2;
   smooth();
  background(255);
  fill(255);
ellipse(100,100,150,150);
int diameter = 150;
float[] angs = {zombies/players*100};
float lastAng = 0;
for (int i = 0; i < angs.length; i++){
 fill(255,0,0);
 arc(width/2, height/2, diameter, diameter, lastAng, lastAng+radians(angs[i]*3.6));
 lastAng += radians(angs[i]*3.6);  
}
fill(255);
ellipse(100,100,100,100);
}

Replies(8)

Okay, so I rewrote my XML to match the XML in the example and I am now able to pull a list of just the "state" attributes.

If I use println, I end up with a list of the word "human" 5 times and the word "zombie" 15 times. Now I'm trying to figure out how to count the number of times zombies appears so that I can get a percentage of zombies to players. Any kind of pointer would help, I'm not even sure where to start. Do I continue to work in XMLElement code, or do I just used the pulled "state" variable outside? What functions might aid me in figuring this out? Thanks.

   <players>
        <name id="1" state="human" kills="0" fed="na">Brian.Klingenfus</name>
<name id="2" state="human" kills="0" fed="na">Allyson.Johnson</name>
<name id="3" state="human" kills="0" fed="na">Justin.Clatterbuck</name>
<name id="4" state="human" kills="0" fed="na">Mike.Guiliani AT</name>
<name id="5" state="human" kills="0" fed="na">Jessica.Wood AT</name>
        <name id="6" state="zombie" kills="3" fed="2010-09-17 16:18:46">Tim.Mace AT</name>
        <name id="7" state="zombie" kills="0" fed="2010-09-17 04:02:00">Angpol Phale</name>
        <name id="8" state="zombie" kills="0" fed="2010-09-18 12:00:00">Sayene Feet</name>
<name id="9" state="zombie" kills="1" fed="2010-09-17 04:02:00">Debel Issttas</name>
<name id="10" state="zombie" kills="2" fed="2010-09-18 12:00:00">Stad Angtia</name>
<name id="11" state="zombie" kills="0" fed="2010-11-09 23:45:33">Ashet Enild</name>
        <name id="12" state="zombie" kills="2" fed="2010-11-09 23:47:06">Sokel Ildup</name>
        <name id="13" state="zombie" kills="0" fed="2010-09-20 00:32:00">Dyum Atub</name>
        <name id="14" state="zombie" kills="1" fed="2010-09-19 18:49:33">Serild Phiser</name>
        <name id="15" state="zombie" kills="0" fed="2010-09-18 21:35:44">Turoldi Osbald</name>
        <name id="16" state="zombie" kills="1" fed="2010-09-17 16:18:46">Sumos Pervesi</name>
        <name id="17" state="zombie" kills="4" fed="2010-09-17 16:18:46">Yerrotho Rispola</name>
        <name id="18" state="zombie" kills="0" fed="2010-09-18 12:00:00">Quevhon Turdra</name>
<name id="19" state="zombie" kills="0" fed="2010-09-17 04:02:00">Ineagea Enhund</name>
        <name id="20" state="zombie" kills="0" fed="2010-09-18 12:00:00">Vukim Iroughi</name>
</players>
 


XMLElement xml;

void setup() {
  size(200, 200);
  xml = new XMLElement(this, "table.xml");
  int numSites = xml.getChildCount();
  for (int i = 0; i < numSites; i++) {
    XMLElement kid = xml.getChild(i);
    String state = kid.getStringAttribute("state"); 
    println(state);    
  }
}
Should be simple enough if there isn't something already built into the xml library...

Before the loop create int variables for each type to store the count.
Inside the loop use a condition to check if state is equal to 'zombie' or 'human' (Make sure you use the String.equals method to do the comparison) and add to the counter variable if it is...
If you defined the XML schema yourself, I advise to avoid a flat structure like that with positional information. Ie. where a tag is associated to tags nearby, only because it is close. For such kind of structure, CSV could be used as well and would be faster to parse!
You could group the data per player, for example:
Copy code
  1. <players>
  2.   <player id="1">
  3.     <name>Brian.Klingenfus</name>
  4.     <state>human</state>
  5.     <kills>0</kills>
  6.     <fed>2010-11-09 23:45:33</fed>
  7.   </player>
  8.   <player id="2">
  9.     <name>Allyson.Johnson ?</name>
  10.     <state>human</state>
  11.     <kills>0</kills>
  12.     <fed>2010-11-09 23:47:06</fed>
  13.   </player>
  14.   ...
  15. </players>
The id has a more logical placement, and sub-data is grouped under a same parent.
Thus, you can iterate on the list of players, and getChildCount() returns the number of players, not of tags.
When iterating, you can get the state sub-children and thus count those with a given value.

[EDIT] Mmm, I shouldn't start an answer on the morning and finish it at night... Well, the advice is still OK, even if the new way you show is OK too. It is often difficult, when making an XML schema, to choose to input data in attributes or between tags.
Okay, I got everything working with the zombie status piece.
Now I'd like to be able to sort out the highest number in the "kills" column and be able to pull all of the info for just that player so that I end up with text that appears in the program like this: "(playerx) is the most dangerous zombie with (y) kills"

Is the string test still the best way to do this? I'm having trouble working out the logic, because all of the methods I can think of would break if there weren't congruous numbers. Let's say the kill set is (1,2,3,5,10). How would I make a loop that wouldn't get stuck at 3 or 5?

Here is what I have so far, I can pull and print the kill values.

I'm still using the my modified XML listed above. 

 XMLElement xml;
  
  xml = new XMLElement(this, "table.xml");
  int numSites = xml.getChildCount();
  for (int i = 0; i < numSites; i++) {
  XMLElement kid = xml.getChild(i);
  String kills = kid.getStringAttribute("kills"); 
  println(kills);
  String ztest1 = kills;
  String ztest2 = "zombie";
  if(ztest1.equals(ztest2) == true) {
  undead = undead + 1;
  }
I don't see a "zombie" string in the kills attributes...
Iterate on the data, get kills as int attribute, if it is higher than the last higher number, set it to this top and assign the current attributes to the data you want to display.
When you say iterate, are you suggesting something specific? From what I understand this is just a general term for using a loop. (I'm new to this type of coding, as you can probably tell.)

Setting it to int instead of String makes sense to me. The rest makes sense in terms of how, logically, I would achieve the program.. but I'm at a loss as to how I might functionally implement this.

For instance, you say "if it is higher than the last higher number," which actually takes a couple of function to achieve. When I do a println on the kills int attribute, I just get a list of the numbers. I don't know how to tell the program to compare numbers within the list. When you say "set it to this top," I'm assuming you mean if a compared number "wins" as being higher and it loses to no other number, then pull this number as the "most kills." But, again, I'm don't really know how to translate that into code.
OK, it is simpler and faster to show some code...
Copy code
  1. void setup()
  2. {
  3.   XMLElement xml = new XMLElement(this, "H:/Temp/Z.xml");
  4.   int numPlayers = xml.getChildCount();
  5.   int maxKills = 0;
  6.   int id = 0;
  7.   String name = "";
  8.   for (int i = 0; i < numPlayers; i++)
  9.   {
  10.     XMLElement player = xml.getChild(i);
  11.     String state = player.getStringAttribute("state");
  12.     int kills = player.getIntAttribute("kills");
  13.     if (kills > maxKills)
  14.     {
  15.       maxKills = kills;
  16.       id = player.getIntAttribute("id");
  17.       name = player.getContent();
  18.     }
  19.   }
  20.   println(name + " (" + id + ") killed " + maxKills);
  21. }

Beautiful. Sometimes the answers seem too simple.

Thanks a ton.