Open an XML file in Codeblocks (C++) using pugixml

1.3k views Asked by At

I've been looking for how to parse an xml file using codeblocks and the library pugixml but I've tried different ways and it still doesn't work.

The XML I have to parse consists on a graph (houses) and my program in C++ is to represent this graph using structs.

XML file looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<WATSON>
  <PHILIPS> 125 </PHILIPS>
  <PEREZ> 254 </PEREZ>
  <SANTOS> 222 </SANTOS>
</WATSON>
<PHILIPS>
    <CENTER> 121 </CENTER>
    <WATSON> 125 </WATSON>
    <SANTOS> 55 </SANTOS>
</PHILIPS>
<PEREZ>
    <WATSON> 254 </WATSON>
    <CENTER> 110 </CENTER>
</PEREZ>

ETC...

The code in C++: (the important part :) )

int main(){
    pugi::xml_document file;

    if (!file.load_file("Sample.xml")){
    cout << "Error loading file XML." << endl;
    system("PAUSE");
    return -1;
}
    pugi::xml_node node;
    getNodeInfo(node);
    cin.get();
    return 0;
}

void getNodeInfo(xml_node node){
    for (xml_node_iterator it = node.begin(); it != node.end(); ++it)
    {
        cout << it->name() << "\n--------\n";
        system("PAUSE");
        for (xml_attribute_iterator ait = it->attributes_begin(); ait != it->attributes_end(); ++ait)
    {
            cout << " " << ait->name() << ": " << ait->value() << endl;
    }
        cout << endl;
        for (xml_node_iterator sit = node.begin(); sit != node.end(); ++sit)
        {
            getNodeInfo(*sit);
    }
}
}

Please tell me, what could be the mistake in the code? It always goes into the if condition, I mean, it doesn't load the file. Thank you!

1

There are 1 answers

4
Galik On

I noticed a couple of errors.

First you are sending an empty node to your function so it has nothing to work on. You should send the file you loaded instead:

int main()
{
    pugi::xml_document file;

    xml_parse_result res;
    if(!(res = file.load_file("test.xml")))
    {
        cout << "Error loading file XML: " << res.description() << endl;
        system("PAUSE");
        return -1;
    }

    pugi::xml_node node; // you are sending an EMPTY node
    // getNodeInfo(node);

    // Send the file you just loaded instead
    getNodeInfo(file);

    cin.get();
    return 0;
}

Also you have a weird loop within a loop thing going on in your function. You are already looping over the node's children, no need for the inner loop over the same children:

void getNodeInfo(xml_node node)
{
    for(xml_node_iterator it = node.begin(); it != node.end(); ++it)
    {
        cout << it->name() << "\n--------\n";
//      system("PAUSE");
        for(xml_attribute_iterator ait = it->attributes_begin();
        ait != it->attributes_end(); ++ait)
        {
            cout << " " << ait->name() << ": " << ait->value() << endl;
        }
        cout << endl;
// You are already in a loop for this node so no need for this
//      for(xml_node_iterator sit = node.begin(); sit != node.end(); ++sit)
//      {
//          getNodeInfo(*sit);
//      }

        // just use the iterator you are already looping over
        getNodeInfo(*it);
    }
}

Finally your XML data is not well formed. It needs an all embracing tag like this:

<?xml version="1.0" encoding="UTF-8"?>
<HOUSES>
    <WATSON att="att1">
        <PHILIPS> 125 </PHILIPS>
        <PEREZ> 254 </PEREZ>
        <SANTOS> 222 </SANTOS>
    </WATSON>
    <PHILIPS>
        <CENTER> 121 </CENTER>
        <WATSON> 125 </WATSON>
        <SANTOS> 55 </SANTOS>
    </PHILIPS>
    <PEREZ>
        <WATSON> 254 </WATSON>
        <CENTER> 110 </CENTER>
    </PEREZ>
</HOUSES>

Hope that helps.