代码之家  ›  专栏  ›  技术社区  ›  dangerousdave

用XeSerCE3.0.1和C++在Windows上编写XML

  •  3
  • dangerousdave  · 技术社区  · 16 年前

    我编写了下面的函数来使用Xerces 3.0.1创建一个XML文件,如果我用文件路径“foo.xml”或“../foo.xml”调用这个函数,效果很好,但是如果我传入“c:/foo.xml”,那么我会在这行得到一个异常。

    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();
    }
    
    4 回复  |  直到 13 年前
        1
  •  1
  •   Community Mohan Dere    9 年前

    您使用的是Windows Vista吗?也许你没有必要的权限? 请参阅此问题: Exception in two line Xerces program

        2
  •  3
  •   Garett    16 年前

    您的文件路径似乎不正确。它应该是file:///c/。有关详细信息,请参阅以下内容:

    http://en.wikipedia.org/wiki/File_URI_scheme

    更新: 以下代码适用于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(); 
    } 
    
        3
  •  1
  •   jon hanson    16 年前

    通过查看文件名传递到的源文件 WindowsFileMgr::fileOpen 在里面 WindowsFileMgr.cpp ,似乎不需要URI。

    因此,您是否尝试过不将文件名转换为URI,例如只使用:

    c:\foo.xml
    

    (可能需要避开反斜杠)

    ?

        4
  •  1
  •   Vigo    13 年前

    运行上述代码可能会导致错误“domdocument”:不明确的符号,在这种情况下,将domdocument替换为xercesc::domdocument,因为在msxml.h头中还定义了一个domdocument类,这会导致不明确。