Rigidness and verbose nature of XML parsing I've been developing a simple console application in C++ using the TinyXML2 library, and I honestly can't help but feel what I'm doing is not very robust. Maybe that's just the nature of parsing XML (this is my first foray into the topic, so I've no idea.)

The following code works to the best of my knowledge, but it feels like there has to be a better way than manually navigating to each element, checking for null pointers, then grabbing the information. Is there a more elegant way to handle this? I have to be missing something within the documentation, because I feel like I'm writing a lot of redundant code here.

#include &lt;iostream&gt;
#include "tinyxml2.h"

int main() {
    tinyxml2::XMLDocument document;

    if (document.LoadFile("games.xml") == tinyxml2::XML_SUCCESS) {
        std::cout &lt;&lt; "'games.xml' successfully loaded." &lt;&lt; std::endl;

        tinyxml2::XMLElement *root = document.RootElement();

        std::cout &lt;&lt; root-&gt;Value() &lt;&lt; std::endl;

        tinyxml2::XMLElement *child;

        for (child = root-&gt;FirstChildElement(); child != nullptr; child = child-&gt;NextSiblingElement()) {
            std::cout &lt;&lt; "\t" &lt;&lt; child-&gt;Value() &lt;&lt; std::endl;

            if (child-&gt;FirstChildElement("name") == nullptr) {
                std::cerr &lt;&lt; "Error: null pointer." &lt;&lt; std::endl;
                return 1;
            }
            if (child-&gt;FirstChildElement("system") == nullptr) {
                std::cerr &lt;&lt; "Error: null pointer." &lt;&lt; std::endl;
                return 1;
            }
            if (child-&gt;FirstChildElement("status") == nullptr) {
                std::cerr &lt;&lt; "Error: null pointer." &lt;&lt; std::endl;
                return 1;
            }
            const char* game_name = child-&gt;FirstChildElement("name")-&gt;GetText();
            const char* game_system = child-&gt;FirstChildElement("system")-&gt;GetText();
            const char* game_status = child-&gt;FirstChildElement("status")-&gt;GetText();

            if (game_name == nullptr || game_system == nullptr || game_status == nullptr) {
                std::cout &lt;&lt; "Error: null pointer." &lt;&lt; std::endl;
                return 1;
            }
            std::cout &lt;&lt; "\t\t" &lt;&lt; game_name &lt;&lt; std::endl;
            std::cout &lt;&lt; "\t\t" &lt;&lt; game_system &lt;&lt; std::endl;
            std::cout &lt;&lt; "\t\t" &lt;&lt; game_status &lt;&lt; std::endl;
        }
    } else {
        std::cerr &lt;&lt; "Unable to load 'games.xml'. Error code: " &lt;&lt; document.ErrorID() &lt;&lt; std::endl;
        return 1;
    }
    return 0;
}
In your code I do agree there more redundancy than I like to see. I would suggest writing some helper functions, and perhaps leveraging exceptions instead of return codes (I won't show that here).

const char* FirstChildElementText(tinyxml2::XMLElement *parent, const char *child_name)
{
    auto child = parent-&gt;FirstChildElement(child_name);
    return (child != nullptr) ? child-&gt;GetText() : nullptr;
}
: : :
for (child = root-&gt;FirstChildElement(); child != nullptr; child = child-&gt;NextSiblingElement()) {
    auto game_name = FirstChildElementText(child, "name");
    auto game_system = FirstChildElementText(child, "system");
    auto game_status = FirstChildElementText(child, "status");

    if (game_name == nullptr || ...)
    : : :
}


This helps a bit. Always be on the lookout for a good refactoring. Even if you already found a better XML library for your needs.

(I have things I dislike about both DOM and SAX style XML parsing, either being too lenient or too much work. Really, all in all, I suspect that directly working with XML is approaching things from the wrong level. But I don't have a great solution, so I'll get off my soap box.)