Search code examples
c++xmltreexercestree-traversal

Preorder traversal of an XML tree with a recursive function?


I have an XML file that looks like this:

<?xml version="1.0"? encoding="UTF-8" standalone="no"?>
<dir name="mint">
  <dir name="pepper">
    <dir name="shauninman">
      <dir name="geomint">
        <file name="readme.txt"/ token="3">
        <file name="blank.gif"/ token="2">
        <file name="class.php"/ token="7"> 
      <dir/>
    <dir/>
  <dir/>
  <dir name="test1">
    <dir name="test2">
      <dir name="test3">
        <file name="foo1.txt"/ token="3">
        <file name="foo2.gif"/ token="5">
        <file name="foo3.php"/ token="5"> 
      <dir/>
      <dir name="test4">
        <file name="foo4.txt"/ token="3">
        <file name="foo5.gif"/ token="5">
        <file name="foo6.php"/ token="5"> 
      <dir/>
    <dir/>
  <dir/>
<dir/>

I once wrote a function in C++ that does a prefix traversal of a tree structure that looks like this:

int traverseTree( Item* node, int id )
{
    cout << id;   
    id = id+1;
    vector<Item*>* children = node->getChildren();

    for( int i = 0; i < children->size(); ++i )
        id = traverseTree( children->at(i), id );

    return id;
}

Now, I want to do the same thing, but from the XML file. In other words, I would like to parse the XML, then send the root to the function "traverseTree". Then, at each recursive call, I could retrive the children of the current node.

How can I use a tool like xerces to accomplish this? What would be the new function?

Thanks for any help!


Solution

  • #include <xercesc/parsers/XercesDOMParser.hpp>
    #include <xercesc/dom/DOM.hpp>
    #include <xercesc/sax/HandlerBase.hpp>
    #include <xercesc/util/XMLString.hpp>
    #include <xercesc/util/PlatformUtils.hpp>
    
    #if defined(XERCES_NEW_IOSTREAMS)
    #include <iostream>
    #else
    #include <iostream.h>
    #endif
    
    XERCES_CPP_NAMESPACE_USE
    
    int main (int argc, char* args[]) {
    
        try {
            XMLPlatformUtils::Initialize();
        }
        catch (const XMLException& toCatch) {
            char* message = XMLString::transcode(toCatch.getMessage());
            cout << "Error during initialization!"<< message << "\n";
            XMLString::release(&message);
            return 1;
        }
    
        XercesDOMParser* parser = new XercesDOMParser();
        parser->setValidationScheme(XercesDOMParser::Val_Always);
        parser->setDoNamespaces(true);    // optional
    
        ErrorHandler* errHandler = (ErrorHandler*) new HandlerBase();
        parser->setErrorHandler(errHandler);
    
        char* xmlFile = "file.xml";
    

    // PARSING ----

        try {
            parser->parse(xmlFile);
        }
        catch (const DOMException& toCatch) {
            char* message = XMLString::transcode(toCatch.msg);
            cout << "Exception message is: \n"
                 << message << "\n";
            XMLString::release(&message);
            return -1;
        }
    

    // GETTING THE DOCUMENT

        DOMDocument* inDoc  = parser->getDocument();
        /* from the document get the pointer to the root */
        DOMNode* inRoot = inDoc->getDocumentElement();
    

    // TRAVERSING

    int traverseTree( DOMNode* node, int id )
    {
    cout << id;   
    id = id+1;
    DOMNodeList* ch_list = node->getChildNodes();
    
    for( int i = 0; i < ch_list->getLength(); ++i )
        id = traverseTree( ch_list->item(i), id );
    
    return id;
    }