XercesC 2.7 не может получить DOMWriter

Я пишу сервер и хочу использовать XML с моим Java-клиентом. Я использую CygWin с XercesC 3.1.1 для своего теста разработки, и это работает нормально (я зациклил 30000 с этой функцией, и у меня не было сбоев). Однако на моей целевой машине работает HP-UX с XercesC 2.7. Чтобы реализовать различия в реализации XercesC, я написал отдельный класс для обработки каждой версии.

Когда я пытаюсь запустить код с помощью XercesC 2.7. Я всегда получаю указатель NULL, когда пытаюсь создать DOMWriter, и SIGABORT при повторной попытке.

Поскольку я ничего не нашел в Google, я надеюсь, что кто-то может пролить свет на то, что я здесь делаю неправильно. Я просматривал пример кода, предоставленный с исходным кодом XercesC, и у меня также есть некоторый производственный код от коллег-программистов, и я не вижу никакой разницы в его работе.

Я попытался создать SSCE, который немного длинноват, но это самый короткий образец, который мне удалось создать.

xml_serialize.h

#ifndef XML_SERIALIZE_H_
#define XML_SERIALIZE_H_

#include <string>

#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/dom/DOM.hpp>
#if defined(XERCES_NEW_IOSTREAMS)
#include <iostream>
#else
#include <iostream.h>
#endif
#include <xercesc/util/OutOfMemoryException.hpp>

class XStr
{
public :
    // -----------------------------------------------------------------------
    //  Constructors and Destructor
    // -----------------------------------------------------------------------
    XStr(const char* const toTranscode)
    {
        // Call the private transcoding method
        fUnicodeForm = xercesc::XMLString::transcode(toTranscode);
    }

    ~XStr()
    {
     xercesc::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()

std::string fromXMLString(XMLCh *oXMLString);

class XMLSerialize
{
private:
        xercesc::DOMImplementation *mImpl;

protected:
        xercesc::DOMImplementation *getDOMImplementation(void);

public:
    XMLSerialize(void);
    virtual ~XMLSerialize(void);

public:

    /**
     * Creates an empty DOM
     */
    xercesc::DOMDocument *createDocument(const std::string &oDocumentName);

    /**
     * Parses an XML from a string.
     */
    xercesc::DOMDocument *parseDocument(const std::string &oDocumentName, std::string const &oReferenceId);

    /**
     * Serializes the document into a string
     */
    int serialize(xercesc::DOMDocument *oDocument, std::string &oXMLOut, bool bDocumentRelease = true);
};

#endif /* XML_SERIALIZE_H_ */

xml_serialize.cpp

#include <xercesc/util/XMLString.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/util/TransService.hpp>
#include <xercesc/framework/MemBufFormatTarget.hpp>
#include <xercesc/util/OutOfMemoryException.hpp>

#include <sstream>
#include <vector>
#include <iostream>

#include "xml_serialize.h"

int serializeEnvironment(void);
XMLSerialize *serializer = NULL;

XMLSerialize::XMLSerialize()
{
    mImpl = xercesc::DOMImplementationRegistry::getDOMImplementation(X("Core"));
}

XMLSerialize::~XMLSerialize()
{
}

xercesc::DOMDocument *XMLSerialize::createDocument(const std::string &oDocumentName)
{
    if(mImpl == NULL)
        return NULL;

    xercesc::DOMDocument *doc = mImpl->createDocument(
            0,                      // root element namespace URI.
            X(oDocumentName.c_str()),       // root element name
            0);                 // document type object (DTD).

    if(doc == NULL)
        return NULL;

    return doc;
}

int XMLSerialize::serialize(xercesc::DOMDocument *oDocument, std::string &oXMLOut, bool bDocumentRelease)
{
    int result = 0;
    XMLCh *xmlUnicode = NULL;
    char *strXML = NULL;
    xercesc::DOMWriter *serializer = NULL;

    if(mImpl == NULL)
    {
        oXMLOut = "ERROR: XercesC DOMImplementationRegistry not initialized";
        result = 1;
        goto Quit;
    }

    serializer = ((xercesc::DOMImplementationLS*)mImpl)->createDOMWriter();
    if(serializer == NULL)
    {
        oXMLOut = "ERROR: XercesC unable to instantiate a DOMWriter!";
        result = 2;
        goto Quit;
    }

    xmlUnicode = serializer->writeToString(*oDocument);
    strXML = xercesc::XMLString::transcode(xmlUnicode);
    oXMLOut = strXML;

    if(bDocumentRelease == true)
        oDocument->release();

    result = 0;

Quit:
    if(strXML != NULL)
        xercesc::XMLString::release(&strXML);

    if(xmlUnicode != NULL)
        xercesc::XMLString::release(&xmlUnicode);

    if(serializer != NULL)
        serializer->release();

    return result;
}

int serializeEnvironment(void)
{
    int errorCode = 0;
    xercesc::DOMElement *rootElem = NULL;
    xercesc::DOMElement *item = NULL;
    xercesc::DOMElement *element = NULL;
    xercesc::DOMText *nameNode = NULL;
    xercesc::DOMCDATASection *dataNode = NULL;
    std::string xml;

    try
    {
        xercesc::DOMDocument *doc = serializer->createDocument("EnvironmentList");
        if(doc == NULL)
            return 1;

        rootElem = doc->getDocumentElement();
        std::vector<std::pair<std::string, std::string> > env;
        for(int i = 0; i < 5; i++)
        {
            std::string key;
            std::string value;

            std::stringstream ss;
            ss << "KEY";
            ss << i;
            ss >> key;
            ss.clear();

            ss << "VALUE";
            ss << i;
            ss >> value;
            ss.clear();

            env.push_back(std::make_pair(key, value));
        }

        for(std::vector<std::pair<std::string, std::string> >::const_iterator it = env.begin(); it != env.end(); ++it)
        {
            std::pair<std::string, std::string>entry = *it;
            std::string name = entry.first;
            std::string value = entry.second;

            if(value.empty())
                value = "";

            item = doc->createElement(X("item"));
            rootElem->appendChild(item);

            element = doc->createElement(X("item"));
            nameNode = doc->createTextNode(X(name.c_str()));
            item->appendChild(element);
            element->appendChild(nameNode);

            element = doc->createElement(X("item"));
            dataNode = doc->createCDATASection(X(value.c_str()));
            item->appendChild(element);
            element->appendChild(dataNode);
        }

        errorCode = serializer->serialize(doc, xml);
        std::cout << xml << std::endl;

        doc->release();
        errorCode = 0;
    }
    catch (const xercesc::OutOfMemoryException&)
    {
        XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl;
        errorCode = 2;
    }
    catch (const xercesc::DOMException& e)
    {
        XERCES_STD_QUALIFIER cerr << "DOMException code is:  " << e.code << XERCES_STD_QUALIFIER endl;
        errorCode = 3;
    }
    catch (...)
    {
        XERCES_STD_QUALIFIER cerr << "An error occurred creating the document" << XERCES_STD_QUALIFIER endl;
        errorCode = 4;
    }

    return errorCode;
}

int main()
{
    xercesc::XMLPlatformUtils::Initialize();

   serializer = new XMLSerialize();

   int error = 0;
   for(int i = 0; i < 2; i++)
   {
    std::cout << "Serializing:" << i << " ... " << std::endl;
    if((error = serializeEnvironment()) != 0)
        std::cout << "ERROR" << error << std::endl;

    std::cout << "Done" << std::endl;
   }

    xercesc::XMLPlatformUtils::Terminate();

    return 0;
}

вывод

Serializing:0 ... 
ERROR: XercesC unable to instantiate a DOMWriter!
Done
Serializing:1 ... 
aCC runtime: pure virtual function called for class "xercesc_2_7::DOMImplementationLS".
Abort(coredump)

обновить

Наконец-то мне удалось скомпилировать 2.7 для cygwin и протестировать приведенный выше код. Это работает нормально, поэтому должна быть какая-то проблема со средой HP-UX.


person Devolus    schedule 30.07.2013    source источник


Ответы (1)


Я компилировал код с помощью gcc, и, очевидно, библиотека xerces была скомпилирована с помощью aCC. Итак, теперь я переключился на aCC в моем make-файле, и теперь он работает.

Следует ожидать, что производимые библиотеки совместимы, но, видимо, это не так. Таким образом, приведенный выше код на самом деле правильный.

person Devolus    schedule 31.07.2013