c++xmlsoapxerces-c

Xerces-C failing while putting colon in root name


I am trying to create a soap WSDL via xerces in C++. I just want to create XML and put it in one file.

While creating xml I am using below code snippet to create xml document

pDomDocument = p_DOMImplementation->createDocument("http://schemas.xmlsoap.org/soap/envelope/",
                               convertStringToXmlCh("soapenv:Envelope"),
                               0);  

But this line is throwing exception while running .Exception is : "Caught dom exception with message :invalid or illegal XML character".

Also my xml has three namespace apart from default namespace. How can I add this via xerces.

But the time I remove colon(:) from root name in createDocument function the flow run. Can you please let me with how can I put namespace name in xml document via xerces.

I tried searching a lot on google without success.

Edit 1:

    DOMImplementation* p_DOMImplementation = NULL;
        p_DOMImplementation = DOMImplementationRegistry::getDOMImplementation(XMLString::transcode("core"));
        DOMDocument* pDomDocument=NULL;

        try
        {
            pDomDocument = p_DOMImplementation->createDocument(convertStringToXmlCh(uri),  //Root element namespace URI
                                                        convertStringToXmlCh(rootNode), // Root element name
                                                         0);  //Document type (DTD)
        }
        catch(DOMException& e)
        {

            BL_LOG_MSG(BL_FATAL,"Caught dom exception with message :<1>",XMLString::transcode(e.getMessage()))
            return NULL;
        } 

edit 2:

Below is my exact code still getting exception:

int main()
{

        DOMImplementation* p_DOMImplementation = NULL;
        XMLPlatformUtils::Initialize();
        p_DOMImplementation = DOMImplementationRegistry::getDOMImplementation(convertStringToXmlCh("Core"));
        DOMDocument* pDomDocument=NULL;

        try
        {
               pDomDocument = p_DOMImplementation->createDocument(convertStringToXmlCh("http://schemas.xmlsoap.org/soap/envelope/"),  //Root element namespace URI
                                                                   convertStringToXmlCh("soapenv:envelope"), // Root element name
                               NULL);  //Document type (DTD)
         }
         catch(DOMException& e)
         {
                cout <<"Caught xception:"<<e.getMessage();
                return NULL;
         }
         catch(...)
         {

                cout <<"Caught xception:";
                return NULL;
         }
         if(pDomDocument == NULL)
         {
                         return NULL;
                        cout<<"NULL returned";
         }

        DOMElement* pRootElement = pDomDocument->getDocumentElement();
        addAttributeToDomElementNS(pRootElement,"xmlns:typ","http://abcd.fg/V1/types");

        char* path = "/users/gen/app/mayank.xml";
        SerializeXmlWriter(pDomDocument,path);

        return 0;
}

Getting below exception: "Caught xception:invalid or illegal XML character"


Solution

  • Here is an example based on the Xerces sample CreateDOMDocument, only creating elements in a namespace. The sample works fine for me on Window 10, compiled against a binary release of xerces-c-3.1.1-x86-windows-vc-10.0:

    #include "stdafx.h"
    
    
    // ---------------------------------------------------------------------------
    //  Includes
    // ---------------------------------------------------------------------------
    #include <xercesc/util/PlatformUtils.hpp>
    #include <xercesc/util/XMLString.hpp>
    #include <xercesc/dom/DOM.hpp>
    #include <xercesc/util/OutOfMemoryException.hpp>
    
    #if defined(XERCES_NEW_IOSTREAMS)
    #include <iostream>
    #else
    #include <iostream.h>
    #endif
    
    
    XERCES_CPP_NAMESPACE_USE
    
    // ---------------------------------------------------------------------------
    //  This is a simple class that lets us do easy (though not terribly efficient)
    //  trancoding of char* data to XMLCh data.
    // ---------------------------------------------------------------------------
    class XStr
    {
    public:
        // -----------------------------------------------------------------------
        //  Constructors and Destructor
        // -----------------------------------------------------------------------
        XStr(const char* const toTranscode)
        {
            // Call the private transcoding method
            fUnicodeForm = XMLString::transcode(toTranscode);
        }
    
        ~XStr()
        {
            XMLString::release(&fUnicodeForm);
        }
    
    
        // -----------------------------------------------------------------------
        //  Getter methods
        // -----------------------------------------------------------------------
        const XMLCh* unicodeForm() const
        {
            return fUnicodeForm;
        }
    
    private:
        // -----------------------------------------------------------------------
        //  Private data members
        //
        //  fUnicodeForm
        //      This is the Unicode XMLCh format of the string.
        // -----------------------------------------------------------------------
        XMLCh*   fUnicodeForm;
    };
    
    #define X(str) XStr(str).unicodeForm()
    
    
    // ---------------------------------------------------------------------------
    //  main
    // ---------------------------------------------------------------------------
    
    int main(int argC, char*[])
    {
        // Initialize the XML4C2 system.
        try
        {
            XMLPlatformUtils::Initialize();
        }
    
        catch (const XMLException& toCatch)
        {
            char *pMsg = XMLString::transcode(toCatch.getMessage());
            XERCES_STD_QUALIFIER cerr << "Error during Xerces-c Initialization.\n"
                << "  Exception message:"
                << pMsg;
            XMLString::release(&pMsg);
            return 1;
        }
    
        // Watch for special case help request
        int errorCode = 0;
        if (argC > 1)
        {
            XERCES_STD_QUALIFIER cout << "\nUsage:\n"
                "    CreateDOMDocument\n\n"
                "This program creates a new DOM document from scratch in memory.\n"
                "It then prints the count of elements in the tree.\n"
                << XERCES_STD_QUALIFIER endl;
            errorCode = 1;
        }
        if (errorCode) {
            XMLPlatformUtils::Terminate();
            return errorCode;
        }
    
        {
            //  Nest entire test in an inner block.
    
    
            DOMImplementation* impl = DOMImplementationRegistry::getDOMImplementation(X("Core"));
    
            if (impl != NULL)
            {
                try
                {
                    DOMDocument* doc = impl->createDocument(
                        X("http://www.w3.org/2000/svg"),                    // root element namespace URI.
                        X("svg:svg"),         // root element name
                        0);                   // document type object (DTD).
    
                    doc->getDocumentElement()->appendChild(doc->createElementNS(X("http://www.w3.org/2000/svg"), X("svg:circle")));
    
                    //
                    // Now count the number of elements in the above DOM tree.
                    //
    
                    const XMLSize_t elementCount = doc->getElementsByTagName(X("*"))->getLength();
                    XERCES_STD_QUALIFIER cout << "The tree just created contains: " << elementCount
                        << " elements." << XERCES_STD_QUALIFIER endl;
    
                    DOMImplementationLS* lsImpl = (DOMImplementationLS*)impl;
                    DOMLSSerializer* ser = lsImpl->createLSSerializer();
    
                    XERCES_STD_QUALIFIER wcout << ser->writeToString(doc);
    
                    doc->release();
                    ser->release();
                }
                catch (const OutOfMemoryException&)
                {
                    XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl;
                    errorCode = 5;
                }
                catch (const DOMException& e)
                {
                    XERCES_STD_QUALIFIER cerr << "DOMException code is:  " << e.code << XERCES_STD_QUALIFIER endl;
                    errorCode = 2;
                }
                catch (...)
                {
                    XERCES_STD_QUALIFIER cerr << "An error occurred creating the document" << XERCES_STD_QUALIFIER endl;
                    errorCode = 3;
                }
            }  // (inpl != NULL)
            else
            {
                XERCES_STD_QUALIFIER cerr << "Requested implementation is not supported" << XERCES_STD_QUALIFIER endl;
                errorCode = 4;
            }
        }
    
        XMLPlatformUtils::Terminate();
        return errorCode;
    }
    

    Output on Windows with VS 2015 is

    The tree just created contains: 2 elements.
    <?xml version="1.0" encoding="UTF-16" standalone="no" ?><svg:svg xmlns:svg="http://www.w3.org/2000/svg"><svg:circle/></svg:svg>
    

    so that works fine and does not exhibit the problem you say you get with your snippets.