c++namespacesheader-filesmsxmlxerces

C++ "'DOMDocument' : redefinition" Error with Xercesc


My problem is that Xerces and Windows both have a 'DOMDocument' object. Xerces and just about everything I've read here, here and here has suggested to define the namespace or undefine DOMDocument which should look something like this.

Void foo(XERCES_CPP_NAMESPACE::DOMDocument* pDocument);

or

#undef DOMDocument
#include <xerces/Stuff>

I wanted to go the sane route and just apply the namespace but it doesn't seem to work. I'm really hesitant to use an #undef that feels like hacking around the problem.

The windows file msxml.h is the one that's complaining about a redefinition.

Could this have to do with the order they are loaded? I have something like this,

#include <stdio.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <list>
#include <map>
#include <ctime>
#include "XMLClass.h"

Where XMLClass.h includes xerces headers. It's really hard to tell whats causing the issue because the error shows up in a microsoft header.

I've also searched for 'DOMDocument' in the whole project and everywhere I use 'DOMDocument' has a namespace of XERCES_CPP_NAMESPACE.

Note: I'm using xerces 3.1 and VS 2010.

Ideas?

Update: I have tried #undef before adding the xerces headers and I'm still receiving the error. So I'm really at a lost as to why both solutions aren't working for me.

Update 2: I've also tried changing the namespace from XERCES_CPP_NAMESPACE::DOMDocument to xercesc::DOMDocument but this has not helped.


Solution

  • It was a header load order problem.

    There are 2 libraries I'm aware of that include msxml.h somewhere inside their code,

    #include<Windows.h>
    

    and

    #include<ole2.h>
    

    In my case #include <Windows.h> happened to be down stream of my #include "XMLClass.h". So the solution was to define msxml.h before xerces like this,

    #include<msxml.h>             //defines DOMDocument first     
    //defines DOMDocument with a different namespace
    #include <xercesc/dom/DOMDocument.hpp>  
    

    Because xerces was mindful of namespaces and Microsoft wasn't, if the headers are defined in reverse order like this,

    #include <xercesc/dom/DOMDocument.hpp>
    #include<msxml.h>
    

    no matter what you do your code will not compile. The compiler will tell you that you are redefining 'DOMDocument', which is actually whats happening. This is because of the way Microsoft wrote msxml.h.

    Hope this helps anyone bumping into this problem.

    Note:

    you must ALWAYS include the namespace when defining 'DOMDocument' objects, parameters and return types like this,

    XERCES_CPP_NAMESPACE::DOMDocument xmlDoc;
    
    void setDoc(XERCES_CPP_NAMESPACE::DOMDocument xmlDoc);
    
    XERCES_CPP_NAMESPACE::DOMDocument getDoc();
    

    or you will continue to receive ambiguity errors or worst it will assume the wrong data-type at run-time.