c++visual-studiotinyxml2

Reading in all sibling's elements with TinyXML


I have a problem with reading an XML file! The code below is for getting a children's values(country) out from the XML file, however I would need to go through all the siblings( all three countries) and I would need a solution, which works with also indefinite numbers of siblings. My xml file looks like this:

<?xml version="1.0"?>
<data>
    <country name ="Liechteinstein">
        <rank>1</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <rank>4</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
    <country name="Panama">
        <rank>68</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>

And I have the code like this:

XMLDocument doc;
doc.LoadFile("test.xml");
tinyxml2::XMLElement* countryElement = doc.FirstChildElement("data")->FirstChildElement("country");


ofstream myfile;
myfile.open("result.txt", ios::out | ios::app );
    for (tinyxml2::XMLElement* child = countryElement->NextSiblingElement()->FirstChildElement(); child != NULL; child = child->NextSiblingElement())
    {
        myfile << child->GetText() << endl;
    }
    myfile.close();

This reads in all the values of the first country, but I would need to read and write to txt file all three country's values. I tried using for cycle to go through the siblings adding

countryElement = countryElement->NextSiblingElement() at the end of the for cycle, but it did not work. Could somebody help me please? Thanks in advance!


Solution

  • I would suggest two loops. One to loop through the countries, and one to loop through the neighbors within:

    int main() {
        tinyxml2::XMLDocument doc;
        doc.LoadFile("test.xml");
        tinyxml2::XMLElement* dataElement = doc.FirstChildElement("data");
    
        std::ofstream myfile;
        myfile.open("result.txt", std::ios::out | std::ios::app);
    
        for (tinyxml2::XMLElement* countryElement = dataElement->FirstChildElement("country");
            countryElement != NULL; countryElement = countryElement->NextSiblingElement())
        {
            myfile << "Country name: " << countryElement->Attribute("name") << std::endl;
            myfile << "Rank: " << countryElement->FirstChildElement("rank")->GetText() << std::endl;
            myfile << "Year: " << countryElement->FirstChildElement("year")->GetText() << std::endl;
            myfile << "gdppc: " << countryElement->FirstChildElement("gdppc")->GetText() << std::endl;
    
            for (tinyxml2::XMLElement* child = countryElement->FirstChildElement("neighbor");
                child != NULL; child = child->NextSiblingElement())
            {
                myfile << "Neighbor: " << child->Attribute("name") << std::endl;
            }
            myfile << std::endl;
        }
        myfile.close();
    }
    

    Output:

    Country name: Liechteinstein
    Rank: 1
    Year: 2008
    gdppc: 141100
    Neighbor: Austria
    Neighbor: Switzerland
    
    Country name: Singapore
    Rank: 4
    Year: 2011
    gdppc: 59900
    Neighbor: Malaysia
    
    Country name: Panama
    Rank: 68
    Year: 2011
    gdppc: 13600
    Neighbor: Costa Rica
    Neighbor: Colombia