C++ 使用Xerces 3.0.1和C+编写XML+;在窗户上
我编写了以下函数来使用Xerces 3.0.1创建XML文件,如果我使用文件路径“foo.XML”或“./foo.XML”调用此函数,效果很好,但是如果我传入“c:/foo.XML”,则这一行会出现异常C++ 使用Xerces 3.0.1和C+编写XML+;在窗户上,c++,xml,exception,xerces,C++,Xml,Exception,Xerces,我编写了以下函数来使用Xerces 3.0.1创建XML文件,如果我使用文件路径“foo.XML”或“./foo.XML”调用此函数,效果很好,但是如果我传入“c:/foo.XML”,则这一行会出现异常 XMLFormatTarget *formatTarget = new LocalFileFormatTarget(targetPath); 有人能解释为什么我的代码适用于相对路径,而不是绝对路径吗? 非常感谢 const int ABSOLUTE_PATH_FILENAME_PREFIX_S
XMLFormatTarget *formatTarget = new LocalFileFormatTarget(targetPath);
有人能解释为什么我的代码适用于相对路径,而不是绝对路径吗?
非常感谢
const int ABSOLUTE_PATH_FILENAME_PREFIX_SIZE = 9;
void OutputXML(xercesc::DOMDocument* pmyDOMDocument, std::string filePath)
{
//Return the first registered implementation that has the desired features. In this case, we are after a DOM implementation that has the LS feature... or Load/Save.
DOMImplementation *implementation = DOMImplementationRegistry::getDOMImplementation(L"LS");
// Create a DOMLSSerializer which is used to serialize a DOM tree into an XML document.
DOMLSSerializer *serializer = ((DOMImplementationLS*)implementation)->createLSSerializer();
// Make the output more human readable by inserting line feeds.
if (serializer->getDomConfig()->canSetParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true))
serializer->getDomConfig()->setParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true);
// The end-of-line sequence of characters to be used in the XML being written out.
serializer->setNewLine(XMLString::transcode("\r\n"));
// Convert the path into Xerces compatible XMLCh*.
XMLCh *tempFilePath = XMLString::transcode(filePath.c_str());
// Calculate the length of the string.
const int pathLen = XMLString::stringLen(tempFilePath);
// Allocate memory for a Xerces string sufficent to hold the path.
XMLCh *targetPath = (XMLCh*)XMLPlatformUtils::fgMemoryManager->allocate((pathLen + ABSOLUTE_PATH_FILENAME_PREFIX_SIZE) * sizeof(XMLCh));
// Fixes a platform dependent absolute path filename to standard URI form.
XMLString::fixURI(tempFilePath, targetPath);
// Specify the target for the XML output.
XMLFormatTarget *formatTarget = new LocalFileFormatTarget(targetPath);
//XMLFormatTarget *myFormTarget = new StdOutFormatTarget();
// Create a new empty output destination object.
DOMLSOutput *output = ((DOMImplementationLS*)implementation)->createLSOutput();
// Set the stream to our target.
output->setByteStream(formatTarget);
// Write the serialized output to the destination.
serializer->write(pmyDOMDocument, output);
// Cleanup.
serializer->release();
XMLString::release(&tempFilePath);
delete formatTarget;
output->release();
}
看起来您的文件路径不正确。应该是file:///C:/. 有关更多信息,请参见以下内容: 更新:以下代码适用于我在Visual Studio 2008中使用的情况。这是一个使用Xerces附带的一些示例和代码的快速破解
#include <windows.h>
#include <iostream>
#include <string>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/util/OutOfMemoryException.hpp>
#include <xercesc/framework/XMLFormatter.hpp>
#include <xercesc/framework/LocalFileFormatTarget.hpp>
#include <xercesc/dom/DOMDocument.hpp>
#include <xercesc/dom/DOMImplementation.hpp>
#include <xercesc/dom/DOMImplementationRegistry.hpp>
#include <xercesc/dom/DOMLSSerializer.hpp>
#include <xercesc/dom/DOMLSOutput.hpp>
using namespace xercesc;
using namespace std;
void OutputXML(xercesc::DOMDocument* pmyDOMDocument, std::string filePath);
class XStr
{
public :
XStr(const char* const toTranscode)
{
// Call the private transcoding method
fUnicodeForm = XMLString::transcode(toTranscode);
}
~XStr()
{
XMLString::release(&fUnicodeForm);
}
const XMLCh* unicodeForm() const
{
return fUnicodeForm;
}
private :
XMLCh* fUnicodeForm;
};
#define X(str) XStr(str).unicodeForm()
int _tmain(int argc, _TCHAR* argv[])
{
try
{
XMLPlatformUtils::Initialize();
}
catch(const XMLException& e)
{
char* message = XMLString::transcode(e.getMessage());
cout << "Error Message: " << message << "\n";
XMLString::release(&message);
return 1;
}
int errorCode = 0;
{
DOMImplementation* impl = DOMImplementationRegistry::getDOMImplementation(X("Core"));
if (impl != NULL)
{
try
{
DOMDocument* doc = impl->createDocument(
0, // root element namespace URI.
X("company"), // root element name
0); // document type object (DTD).
DOMElement* rootElem = doc->getDocumentElement();
DOMElement* prodElem = doc->createElement(X("product"));
rootElem->appendChild(prodElem);
DOMText* prodDataVal = doc->createTextNode(X("Xerces-C"));
prodElem->appendChild(prodDataVal);
DOMElement* catElem = doc->createElement(X("category"));
rootElem->appendChild(catElem);
catElem->setAttribute(X("idea"), X("great"));
DOMText* catDataVal = doc->createTextNode(X("XML Parsing Tools"));
catElem->appendChild(catDataVal);
DOMElement* devByElem = doc->createElement(X("developedBy"));
rootElem->appendChild(devByElem);
DOMText* devByDataVal = doc->createTextNode(X("Apache Software Foundation"));
devByElem->appendChild(devByDataVal);
OutputXML(doc, "C:/Foo.xml");
doc->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(const XMLException& e)
{
char* message = XMLString::transcode(e.getMessage());
cout << "Error Message: " << message << endl;
XMLString::release(&message);
return 1;
}
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;
}
void OutputXML(xercesc::DOMDocument* pmyDOMDocument, std::string filePath)
{
//Return the first registered implementation that has the desired features. In this case, we are after a DOM implementation that has the LS feature... or Load/Save.
DOMImplementation *implementation = DOMImplementationRegistry::getDOMImplementation(L"LS");
// Create a DOMLSSerializer which is used to serialize a DOM tree into an XML document.
DOMLSSerializer *serializer = ((DOMImplementationLS*)implementation)->createLSSerializer();
// Make the output more human readable by inserting line feeds.
if (serializer->getDomConfig()->canSetParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true))
serializer->getDomConfig()->setParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true);
// The end-of-line sequence of characters to be used in the XML being written out.
serializer->setNewLine(XMLString::transcode("\r\n"));
// Convert the path into Xerces compatible XMLCh*.
XMLCh *tempFilePath = XMLString::transcode(filePath.c_str());
// Specify the target for the XML output.
XMLFormatTarget *formatTarget = new LocalFileFormatTarget(tempFilePath);
// Create a new empty output destination object.
DOMLSOutput *output = ((DOMImplementationLS*)implementation)->createLSOutput();
// Set the stream to our target.
output->setByteStream(formatTarget);
// Write the serialized output to the destination.
serializer->write(pmyDOMDocument, output);
// Cleanup.
serializer->release();
XMLString::release(&tempFilePath);
delete formatTarget;
output->release();
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间xercesc;
使用名称空间std;
void OutputXML(xercesc::DOMDocument*pmyDOMDocument,std::string filePath);
类XStr
{
公众:
XStr(常量字符*常量toTranscode)
{
//调用私有转码方法
fUnicodeForm=XMLString::转码(toTranscode);
}
~XStr()
{
XMLString::release(&fUnicodeForm);
}
常量XMLCh*unicodeForm()常量
{
回归函数;
}
私人:
XMLCh*funicoderm;
};
#定义X(str)XStr(str).unicodeForm()
int _tmain(int argc,_TCHAR*argv[]
{
尝试
{
XMLPlatformUtils::Initialize();
}
捕获(常量XMLException&e)
{
char*message=XMLString::transcode(例如getMessage());
cout createElement(X(“产品”));
rootElem->appendChild(prodElem);
DOMText*prodDataVal=doc->createTextNode(X(“Xerces-C”);
prodElem->appendChild(prodDataVal);
doElement*catElem=doc->createElement(X(“类别”);
rootElem->appendChild(catElem);
catElem->setAttribute(X(“想法”),X(“伟大”);
DOMText*catDataVal=doc->createTextNode(X(“XML解析工具”);
catElem->appendChild(catDataVal);
doElement*devbylem=doc->createElement(X(“developedBy”);
rootElem->appendChild(devbylem);
DOMText*devByDataVal=doc->createTextNode(X(“Apache软件基金会”);
devbylem->appendChild(devByDataVal);
OutputXML(doc,“C:/Foo.xml”);
doc->release();
}
捕获(常量OutOfMemoryException&)
{
XERCES_STD_QUALIFIER cerr从查看文件名传递到中的WindowsFileMgr::fileOpen
的源文件,该文件似乎不需要URI
那么,您是否尝试过不将文件名转换为URI,例如仅使用:
c:\foo.xml
(可能需要避开反斜杠)
?您正在使用Windows Vista吗?也许您没有必要的权限?
查看此问题:运行上述代码可能会出现错误-'DOMDocument':不明确的符号,在这种情况下,将DOMDocument替换为xercesc::DOMDocument,因为msxml.h标头中还定义了一个导致不明确的DOMDocument类。感谢Garett的回复,我调用XMLString::fixURI以获得该格式的路径s传递给LocalFileFormatTarget的字符串:”file:///c:/foo.xml“您收到了什么错误消息?我假设您已将其包装在try/catch中。无法打开文件”file:///c:/foo.xml'您是否尝试过使用GetLastError()和FormatMessage来获取windows错误描述?我用您的代码进行了尝试,得到了“文件名、目录名或卷标语法不正确”有趣的是,我尝试了您建议的方法,它适用于相对路径,但对于绝对路径也有相同的异常。“无法打开文件'c:\foo.xml'“不过简化了我的代码,谢谢!你正在链接到xerces的调试版本吗?你应该能够进入我上面提到的函数,添加并查看对Windows CreateFileW函数的调用。+1,因为我有相同的问题。我认为你选择的正确答案不能解决问题,尽管我有必要的权限。”(相对路径和绝对路径的文件位置相同,相对有效,绝对无效)。你是如何解决你的问题的???我很确定这对我来说是一个权限问题,如果我没记错的话,我试图在Vista下写入C驱动器的根目录,但它不允许。谢谢Jon。我想你一定是对的。我在xerces包装器中修复了一些其他问题,现在它可以使用相对和绝对。还有“/”和“\\”目录分隔符:)