Ошибка Xerces-C при вводе двоеточия в корневое имя

Я пытаюсь создать мыльный WSDL через xerces на С++. Я просто хочу создать XML и поместить его в один файл.

При создании xml я использую приведенный ниже фрагмент кода для создания XML-документа.

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

Но эта строка выдает исключение во время работы. Исключение: «Поймано исключение dom с сообщением: недопустимый или недопустимый символ XML».

Также мой xml имеет три пространства имен, кроме пространства имен по умолчанию. Как я могу добавить это через xerces.

Но когда я удаляю двоеточие (:) из корневого имени в функции createDocument, поток запускается. Не могли бы вы рассказать мне, как я могу поместить имя пространства имен в XML-документ через xerces.

Я пытался много искать в Google без успеха.

Редактировать 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;
        } 

редактировать 2:

Ниже мой точный код все еще получает исключение:

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;
}

Получение ниже исключения: «Пойманное исключение: недопустимый или недопустимый символ XML»


person Mayank Jain    schedule 20.03.2016    source источник
comment
Возможно, по умолчанию реализация не поддерживает пространство имен. Как вы создаете реализацию?   -  person Martin Honnen    schedule 20.03.2016
comment
Попробуйте getDOMImplementation(XMLString::transcode("Core XML"), чтобы узнать, поддерживает ли это пространства имен. Я не думаю, что только Core поддерживает пространства имен.   -  person Martin Honnen    schedule 20.03.2016
comment
Или, возможно, getDOMImplementation(XMLString::transcode("Core 2.0") — это способ обеспечить поддержку пространств имен, поскольку DOM Level 1.0 не включает поддержку пространств имен.   -  person Martin Honnen    schedule 20.03.2016
comment
@MartinHonnen- Где я могу найти действительные значения и проверить это?   -  person Mayank Jain    schedule 20.03.2016
comment
w3.org/DOM/DOMTR содержит спецификации. Однако я не знаком с Xerces C++ и тем, как спецификации DOM переводятся в C++.   -  person Martin Honnen    schedule 20.03.2016
comment
@MartinHonnen - не работает даже после изменения реализации. Любое другое предложение?   -  person Mayank Jain    schedule 21.03.2016
comment
Какая версия Xerces C++? Вчера я взял последнюю двоичную версию, которую смог найти (3.1.1), и попробовал ее с VS 2015 в Windows, и некоторый код, следующий за предоставленным образцом CreateDOMDocument, отлично работал у меня, даже при попытке создать SVG с пространством имен. Не было необходимости указывать какую-либо версию, и код, выполняющий DOMDocument* doc = impl->createDocument(X("http://www.w3.org/2000/svg"), X("svg:svg"), 0); и doc->getDocumentElement()->appendChild(doc->createElementNS(X("http://www.w3.org/2000/svg"), X("svg:circle")));, работал нормально. Так и не смог воспроизвести проблему.   -  person Martin Honnen    schedule 21.03.2016
comment
3.1.1 Unix. Как это было реализовано, когда работало?   -  person Mayank Jain    schedule 21.03.2016
comment
Я поместил код, который пробовал, в ответ, чтобы мы могли обменяться кодом. Я понимаю, что это может не ответить на ваш вопрос, но добавление в комментарий подробного кода C++ также не имеет смысла.   -  person Martin Honnen    schedule 21.03.2016
comment
Работает ли это сейчас для вас?   -  person Martin Honnen    schedule 22.03.2016
comment
@MartinHonnen - я добавил последний код и исключение как часть редактирования 2. Не могли бы вы помочь?   -  person Mayank Jain    schedule 24.03.2016
comment
@MartinHonnen - Большое спасибо за вашу помощь. Вопрос решился. Я добавил разрешение в комментарии к вашему коду.   -  person Mayank Jain    schedule 24.03.2016


Ответы (1)


Вот пример, основанный на образце Xerces CreateDOMDocument, в котором создаются только элементы в пространстве имен. Образец отлично работает для меня в Window 10, скомпилирован для бинарной версии 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;
}

Вывод в Windows с VS 2015:

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>

так что это работает нормально и не демонстрирует проблемы, о которой вы говорите, что сталкиваетесь со своими фрагментами.

person Martin Honnen    schedule 21.03.2016
comment
Вопрос решился. Проблема заключалась в том, что функция, которую я использовал для преобразования из String в XMLCh *, была неправильной. Я изменил на один в приведенном выше коде, и это сработало. - person Mayank Jain; 24.03.2016