C++ Xercesc2.7未能获得DOMWriter
我正在编写一个服务器,我想在Java客户机上使用XML。我在Xercesc3.1.1中使用CygWin进行开发测试,效果很好(我用这个函数循环了30000次,没有崩溃)。然而,在我的目标机器上,它运行的是带有XercesC 2.7的HP-UX。为了实现XercesC实现中的差异,我编写了一个单独的类来处理每个版本 当我尝试使用Xercesc2.7运行代码时。当我尝试创建DOMWriter时,我总是得到一个空指针,当我再次尝试时,我总是得到一个SIGABORT 既然我在谷歌上找不到任何东西,我希望有人能解释一下我在这里做错了什么。我一直在看XercesC souorce提供的示例代码,我还有一些来自其他程序员的产品代码,我看不出有什么区别 我试图创建一个有点长的SSCE,但这是我能创建的最短的示例 xml\u serialize.hC++ Xercesc2.7未能获得DOMWriter,c++,xml-serialization,xerces-c,C++,Xml Serialization,Xerces C,我正在编写一个服务器,我想在Java客户机上使用XML。我在Xercesc3.1.1中使用CygWin进行开发测试,效果很好(我用这个函数循环了30000次,没有崩溃)。然而,在我的目标机器上,它运行的是带有XercesC 2.7的HP-UX。为了实现XercesC实现中的差异,我编写了一个单独的类来处理每个版本 当我尝试使用Xercesc2.7运行代码时。当我尝试创建DOMWriter时,我总是得到一个空指针,当我再次尝试时,我总是得到一个SIGABORT 既然我在谷歌上找不到任何东西,我希望
#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_ */
更新
我最终为cygwin编译了2.7,并在那里测试了上述代码。这很好,因此HP-UX环境一定有问题。我是用
gcc
编译代码的,xerces库是用aCC
编译的。所以不,我在makefile中切换到aCC
,现在它可以工作了
人们应该期望生成的库是兼容的,但显然不是这样。所以上面的代码实际上是正确的
#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)