c++xmlloopsrecursionpugixml

How to loop n times, one level per loop in an xml file


This is something that I feel should be easy, but after many hours I still can't figure it out. I tried googling it but it would seem the only way my brain wants to ask the question is in 3 lines of explanation, which doesn't really work with google. Feel free to edit if you have a better way to phrase it.

I have an xml file, say this:

<tag1>
    <tag2>
        <tag3>
            ...
        </tag3>
    </tag2>
</tag1>

The document may have many tag1, tag2 and tag3 per parent.

Using pugixml for c++, I want to perform an action on the selected node. Here's pseudo-code of what I'd like to accomplish, but in a way that I know is wrong and not really doable.

for(pugi::xml_node tag1 : doc->child("tag1").children()){
   //Do something with tag1
   for(pugi::xml_node tag2 : doc->child("tag1").child("tag2").children()){
       //Do something with tag2
       for(pugi::xml_node tag3 : doc->child("tag1").child("tag2").child("tag3").children()){
            //Do something with tag3
       }
   }

}

Just looking at this, it's pretty simple to find what won't work... I need to be able to interact with the doc.child().child().child().child()..... inside the loop. Having to add the .child() for each iteration prevents me from doing something of the recursive style, such as:

void loopXNestedTimes(int n){

   if(n==0) return;
   // Do my stuff
   loopXNestedTimes(n-1);
}

Any clue how I'd go about it? I'm using Qt and c++, but am still learning both, so there might be language features I'm missing that allow this.


Solution

  • Use tag1 to get tag2 elements (and not doc) and use tag2 to get tag3 elements, which I think is the crucial point that you're missing.

    Your code snippet should look like this:

    for (pugi::xml_node tag1 : doc->child("tag1").children()){
       //Do something with tag1
       for (pugi::xml_node tag2 : tag1.child("tag2").children()){
           //Do something with tag2
           for (pugi::xml_node tag3 : tag2.child("tag3").children()){
                //Do something with tag3
           }
       }
    }