2

this is pretty much the first C++ program that I ever made, it should display a list of xml nodes in the document. I made an exact same thing work using TinyXML, but I find Pugi much nicer and would like to continue using it.

Program code:

#include <iostream>
#include <string>
#include <vector>
using namespace std;


#include "pugixml/src/pugixml.hpp"
#include "pugixml/src/pugiconfig.hpp"
#include "pugixml/src/pugixml.cpp"
using namespace pugi;

const char * identify(xml_node node)
{
    const char * type;
    switch(node.type())
    {
        case node_null:
            type = "Null";
            break;
        case node_document:
            type = "Document";
            break;
        case node_element:
            type = "Element";
            break;
        case node_pcdata:
            type = "PCDATA";
            break;
        case node_cdata:
            type = "CDATA";
            break;
        case node_comment:
            type = "Comment";
            break;
        case node_pi:
            type = "Pi";
            break;
        case node_declaration:
            type = "Declaration";
            break;
        case node_doctype:
            type = "Doctype";
            break;
        default:
            type = "Invalid";
    }
    return type;
}

void walk(xml_node parent)
{
    printf("%s:\t%s\t%s\n", identify(parent), parent.name(), parent.value());
    for(xml_node child = parent.first_child(); child != 0; child = parent.next_sibling())
    {
        walk(child);
    }
}

int main(int argc, char* argv[])
{
    for (int i=1; i<argc; i++)
    {
        xml_document doc;
        xml_parse_result result = doc.load_file(argv[i]);

        cout << argv[i] << ": " << result.description() << endl;

        if (result)
        {
            walk(doc);
        }
    }

    return 0;
}

Sample XML:

<?xml version="1.0" encoding="iso-8859-1" standalone="yes"?> 
<iOne>
    <iTwo>
        <iThree>
            <one>1</one>
            <two>2</two>
            <three>3</three>
        </iThree>
    </iTwo>

    <one>1</one>
    <two>2</two>
    <three>3</three>

</iOne>

The code works until it comes across the first of the two <three>s and goes into an infinite loop, which mades me think there is something wrong with condition in for(xml_node child = parent.first_child(); child != 0; child = parent.next_sibling()) but everything is the same as in examples? I probably missed something pretty obvious... these are my first baby steps in c++ though :)

I am given to understand NULL in C++ is just 0 right?

Also (sorry for asking multiple questions), is this really a correct way of doing stuff with pugi? For a C++ program, I dont seem to be using pointers much? Im confused.

1 Answer 1

5

Have you tried changing that for loop to:

for(xml_node child = parent.first_child(); child; child = child.next_sibling())

This is how the samples do it (traverse_base.cpp for example).

The important part is child = child.next_sibling(), not parent.next_sibling().

Sign up to request clarification or add additional context in comments.

3 Comments

Yeah, that is what I actually had originally, it still goes into infinite loop.
updated my answer - I think that's more likely than the previous thing I mentionned.
The "important part" help save me more hours of searching for the problem. Thanks @Mat

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.