title: Proper way to parse XML using pugixml
body: <p>I have an XML file that I need to parse and I'm struggling with using <code>PugiXML</code> to parse out all elements and attributes.</p>
  
  <p>I have the following XML file:</p>
  
  <pre><code>    &lt;?xml version = '1.0' encoding = 'UTF-8'?&gt;
      &lt;PanelList DefaultTheme="konami" &gt;
              &lt;Panel xpos="0" ypos="0" width="800" height="600" imagepath="./%THEME%/background_uga_large.png" name="AttractMode0" &gt;
                  &lt;GameViewport xpos="0" ypos="0" width="630" height="526" name="gameviewport"/&gt;
                  &lt;ValueLabel xpos="120" ypos="550" width="448" height="30" fontsize="18" color="white" text="Please, insert your card" name="StatusAttract" errorimagepath="./%THEME%/panel_top_error.png" pageattpendingpath="./%THEME%/panel_top_att.png" drinkpendingpath="./%THEME%/panel_top_drink.png" onclick="ShowPanel(special_panel999)" /&gt;
                  &lt;StreamingImage xpos="637" ypos="3" width="160" height="120" volume="0" text="udp:@:9001" name="attract1" /&gt;
                  &lt;Image xpos="637" ypos="130" width="160" height="390" imagepath="http://n2web/images/attract-uga.gif" /&gt;
                  &lt;FunctionButton xpos="6" ypos="534" width="68" height="60" imagepath="./%THEME%/button_shrink.png" clickimagepath="./%THEME%/button_shrink_down.png" name="window" onclick="ShowPanel(AttractModeSmall)"/&gt;
                  &lt;FunctionButton xpos="650" ypos="534" width="68" height="60" imagepath="./%THEME%/button_attendantstart_up.png" clickimagepath="./%THEME%/button_attendantstart_down.png" name="pageattstart" onclick="PageAttendantRequest" enable="MW_ONLINE == TRUE"/&gt;
                  &lt;FunctionButton xpos="725" ypos="534" width="68" height="60" imagepath="./%THEME%/button_drinkstart_up.png" clickimagepath="./%THEME%/button_drinkstart_down.png" name="drinkstart" onclick="DrinkRequest" enable="MW_ONLINE == TRUE"/&gt;
              &lt;/Panel&gt;
  
              &lt;Panel xpos="0" ypos="0" width="800" height="600" imagepath="./%THEME%/background_uga_large.png" name="AttractMode1" &gt;
                  &lt;GameViewport xpos="0" ypos="0" width="630" height="526" name="gameviewport"/&gt;
                  &lt;ValueLabel xpos="120" ypos="550" width="448" height="30" fontsize="18" color="white" text="Please, insert your card" name="StatusAttract" errorimagepath="./%THEME%/panel_top_error.png" pageattpendingpath="./%THEME%/panel_top_att.png" drinkpendingpath="./%THEME%/panel_top_drink.png" onclick="ShowPanel(special_panel999)" /&gt;
                  &lt;StreamingImage xpos="637" ypos="3" width="160" height="120" volume="0" text="udp:@:9001" name="attract1" /&gt;
                  &lt;Image xpos="637" ypos="130" width="160" height="390" imagepath="http://n2web/images/attract-uga.gif" /&gt;
                  &lt;FunctionButton xpos="6" ypos="534" width="68" height="60" imagepath="./%THEME%/button_shrink.png" clickimagepath="./%THEME%/button_shrink_down.png" name="window" onclick="ShowPanel(AttractModeSmall)"/&gt;
                  &lt;FunctionButton xpos="650" ypos="534" width="68" height="60" imagepath="./%THEME%/button_attendantstart_up.png" clickimagepath="./%THEME%/button_attendantstart_down.png" name="pageattstart" onclick="PageAttendantRequest" enable="MW_ONLINE == TRUE"/&gt;
                  &lt;FunctionButton xpos="725" ypos="534" width="68" height="60" imagepath="./%THEME%/button_drinkstart_up.png" clickimagepath="./%THEME%/button_drinkstart_down.png" name="drinkstart" onclick="DrinkRequest" enable="MW_ONLINE == TRUE"/&gt;
              &lt;/Panel&gt;    
  &lt;/PanelList&gt;
  </code></pre>
  
  <p>With the following code I can get the attributes of each of the two "Panel" objects.</p>
  
  <pre><code>#include "pugixml.hpp"
  #include &lt;iostream&gt;
  
  int main()
  {
      pugi::xml_document doc;
      if (!doc.load_file("allpanels.xml")) return -1;
  
  
      pugi::xml_node panels = doc.child("PanelList");
  
      std::cout &lt;&lt; panels.name() &lt;&lt; std::endl;
  
      for (pugi::xml_node panel = panels.first_child(); panel; panel = panel.next_sibling())
      {
          std::cout &lt;&lt; panel.name() &lt;&lt; std::endl;
  
          for (pugi::xml_attribute attr = panel.first_attribute(); attr; attr = attr.next_attribute())
          {
              std::cout &lt;&lt; " " &lt;&lt; attr.name() &lt;&lt; "=" &lt;&lt; attr.value() &lt;&lt; std::endl;
          }
          std::cout &lt;&lt; std::endl;
      }
      std::cout &lt;&lt; std::endl;
  }
  </code></pre>
  
  <p>The output is as follows:</p>
  
  <pre><code>jrnVM gtkSign $ ./gtkSign 
  PanelList
  Panel
   xpos=0
   ypos=0
   width=800
   height=600
   imagepath=./%THEME%/background_uga_large.png
   name=AttractMode0
  
  Panel
   xpos=0
   ypos=0
   width=800
   height=600
   imagepath=./%THEME%/background_uga_large.png
   name=AttractMode1
  </code></pre>
  
  <p>I can see that I'm getting the attributes for each of the two "Panel" objects, but not the elements for each. Each "Panel" object in the file will have different elements so I can't traverse the tree looking for particular elements or attributes.</p>
  
  <p><strong>The question is:</strong> How do I modify the code so that I can iterate though all of the "Panel" objects and get all of the information for each one?</p>
  
  <p>Any help would be greatly appreciated.</p>
  
  <p><strong>EDIT:</strong></p>
  
  <p>With the help of "john" I was able to come up with this solution. Thanks John.</p>
  
  <pre><code>#include "pugixml.hpp"
  #include &lt;iostream&gt;
  #include &lt;sstream&gt;
  
  int main()
  {
      pugi::xml_document doc;
      std::string namePanel;
  
      if (!doc.load_file("allpanels.xml")) return -1;
  
  
      pugi::xml_node panels = doc.child("PanelList");
  
      std::cout &lt;&lt; panels.name() &lt;&lt; std::endl;
  
      for (pugi::xml_node panel = panels.first_child(); panel; panel = panel.next_sibling())
      {
          //We found a "Panel" -- print it's attributes
          for (pugi::xml_attribute attr = panel.first_attribute(); attr; attr = attr.next_attribute())
          {
              std::cout &lt;&lt; " " &lt;&lt; attr.name() &lt;&lt; "=" &lt;&lt; attr.value() &lt;&lt; std::endl;
  
              std::string attrName = attr.name();
              if( !attrName.compare("name") )
              {
                  namePanel = attr.value();
              }
          }
          std::cout &lt;&lt; std::endl;
  
          std::cout &lt;&lt; "Panel: "  &lt;&lt; namePanel &lt;&lt; std::endl;
          //Now print all elements and attributes of current "Panel"
          for (pugi::xml_node child = panel.first_child(); child; child = child.next_sibling())
          {
              std::cout &lt;&lt; child.name() &lt;&lt; std::endl;     // get element name
              // iterate through all attributes
              for (pugi::xml_attribute attr = child.first_attribute(); attr; attr = attr.next_attribute())
              {
                  std::cout &lt;&lt; " " &lt;&lt; attr.name() &lt;&lt; "=" &lt;&lt; attr.value() &lt;&lt; std::endl;
              }
              std::cout &lt;&lt; std::endl;
          }
      }
      std::cout &lt;&lt; std::endl;
  }
  </code></pre>
  
  <p><strong>EDIT:</strong> The above works, but I can't help but think there is a better way that involves a single loop.</p>