トップ | puarts.com
メモ  |  制作記  |  開発記  |  日常の記録  |  デジタルコンテンツ制作  |  ファイアーエムブレム  |  ゲーム  |  C/C++  |  C#  |  PC/ソフトウェア  |  Web 開発  |  スクリプト言語  |  その他プログラミング  |  
「Xerces」に関連する記事一覧

0  

Xerces C++ メモリ解放忘れ防止用ラッパークラス

2013/02/11

Xerces C++でリソースの解放忘れをしないようにリソースの確保と解放を行うクラスを作りました。

エラーハンドリングはかなりいい加減なのでその辺は参考にしない方がいいかと思いますが、このようにメモリの明示的な解放が必要なモジュールをクラスでラップしておくと、うっかり解放忘れを防げるのでメモリリーク対策に有効です。


class XercesWapper
{
public:
    enum Result{
        XERCES_RESULT_SUCCESS,
        XERCES_RESULT_NOT_INITIALIZED,
        XERCES_RESULT_XML_ERROR,
        XERCES_RESULT_DOM_ERROR,
        XERCES_RESULT_NO_DOM_IMPLEMENTATION,
        XERCES_RESULT_DOCUMENT_IS_NULL,
        XERCES_RESULT_UNKNOWN_ERROR
    };
public:
    XercesWapper()
        : xerces_initialized_(false)
        , responsible_to_release_xdoc_(false)
        , parser_(NULL)
        , err_handler_(NULL)
        , xdoc_(NULL)
        , root_elem_(NULL)
        , dom_impl_(NULL)
    {
        try
        {
            XMLPlatformUtils::Initialize();
        }
        catch(const XMLException& e)
        {
            char* message = XMLString::transcode(e.getMessage());
            fprintf(stderr, "Error during initialization! : %s\n", message);
            XMLString::release(&message);
            return;
        }
        catch (...) 
        {  
            fprintf( stderr, "Unexpected Exception \n" );  
            return;  
        }
        xerces_initialized_ = true;

        dom_impl_    = DOMImplementationRegistry::getDOMImplementation(XMLString::transcode("Core"));
        err_handler_ = (ErrorHandler*) new HandlerBase();
        parser_      = new XercesDOMParser();
        parser_->setErrorHandler(err_handler_);
    }
    ~XercesWapper()
    {
        if( xerces_initialized_ )
        {
	        if( xdoc_!=NULL&& responsible_to_release_xdoc_ )
	        {
	            xdoc_->release();
	        }
	        delete parser_;
	        delete err_handler_;

            XMLPlatformUtils::Terminate();
        }
    }
    bool xerces_initialized() const{ return xerces_initialized_; }
    DOMDocument* xdoc(){ return xdoc_; }
    DOMElement*  root_elem(){ return root_elem_; }
    DOMImplementation* dom_impl(){ return dom_impl_; }

    XercesWapper::Result ParseXml( const char* xml_path )
    {
        if( xerces_initialized_==false ){ return XercesWrapper::XERCES_RESULT_NOT_INITIALIZED; }
        try
        {
            parser_->parse(xml_path);
        }
        catch( const XMLException& e )
        {
            char* message = XMLString::transcode(e.getMessage());  
            fprintf( stderr, "Exception message is: %s\n", message ); 
            XMLString::release(&message);
            XMLPlatformUtils::Terminate();
            return XercesWapper::XERCES_RESULT_XML_ERROR;
        }
        catch (const DOMException& e) 
        {  
            char* message = XMLString::transcode(e.msg);  
            fprintf( stderr, "Exception message is: %s\n", message ); 
            XMLString::release(&message);  
            XMLPlatformUtils::Terminate();
            return XercesWapper::XERCES_RESULT_DOM_ERROR;  
        }
        catch (...) 
        {  
            fprintf( stderr, "Unexpected Exception \n" ); 
            XMLPlatformUtils::Terminate();
            return XercesWapper::XERCES_RESULT_UNKNOWN_ERROR;
        }
        xdoc_ = parser_->getDocument();
        root_elem_ = xdoc_->getDocumentElement();

        return XercesWapper::XERCES_RESULT_SUCCESS;
    }

    XercesWapper::Result CreateDocument( const char* root_name )
    {
        if( xerces_initialized_==false ){ return XercesWrapper::XERCES_RESULT_NOT_INITIALIZED; }
        if( dom_impl_==NULL ){ return XercesWapper::XERCES_RESULT_NO_DOM_IMPLEMENTATION; }

        xdoc_ = dom_impl_->createDocument(
                                        0,                    // root element namespace URI.
                                        XMLString::transcode(root_name),  // root element name
                                        0);                   // document type object (DTD).

        root_elem_ = xdoc_->getDocumentElement();

        responsible_to_release_xdoc_ = true;

        return XercesWapper::XERCES_RESULT_SUCCESS;
    }

    XercesWapper::Result OutputDocument( const char* ouput_xml_path )
    {
        if( xerces_initialized_==false ){ return XercesWrapper::XERCES_RESULT_NOT_INITIALIZED; }
        if( xdoc_==NULL ) { return XERCES_RESULT_DOCUMENT_IS_NULL; }

	    DOMImplementation *implementation = DOMImplementationRegistry::getDOMImplementation(L"LS");
	    DOMLSSerializer *serializer = ((DOMImplementationLS*)implementation)->createLSSerializer();
	    if (serializer->getDomConfig()->canSetParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true)){
	        serializer->getDomConfig()->setParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true);
	    }
	    serializer->setNewLine(XMLString::transcode("\r\n")); 
	    XMLCh *tempFilePath = XMLString::transcode(ouput_xml_path);
	    XMLFormatTarget *formatTarget = new LocalFileFormatTarget(tempFilePath);
	    DOMLSOutput *output = ((DOMImplementationLS*)implementation)->createLSOutput();
	    output->setByteStream(formatTarget);
	    serializer->write(xdoc_, output);
	
	    serializer->release();
	    XMLString::release(&tempFilePath);
	    delete formatTarget;
	    output->release();

        return XercesWapper::XERCES_RESULT_SUCCESS; 
    }

    DOMElement* CreateElement( const char* elem_name )
    {
        if( xdoc_==NULL ) { return NULL; }

        return xdoc_->createElement(XMLString::transcode(elem_name));
    }
private:
    XercesWrapper( const XercesWrapper &rhs );
    XercesWrapper &operator=( const XercesWrapper &rhs );
private:
    XercesDOMParser*   parser_;
    ErrorHandler*      err_handler_;
    DOMDocument*       xdoc_;
    DOMElement*        root_elem_;
    DOMImplementation* dom_impl_;
    bool               xerces_initialized_;
    bool               responsible_to_release_xdoc_;
};

Xerces-C++ リンク失敗でビルドできない問題の解決策

2011/08/22
C++アプリケーションでXMLを扱うためにXercesを使おうとしたらちゃんとライブラリをリンクしているのにも関わらず次のようなリンクエラーが発生しました。同じエラーに遭遇してしまった方がいるかもしれないので、そのときの解決策を書いておきます。
error LNK2019: unresolved external symbol "__declspec(dllimport) public: static char * __cdecl xercesc_3_1::XMLString::transcode(unsigned short const * const,class xercesc_3_1::MemoryManager * const)"
error LNK2001: unresolved external symbol "public: virtual void __cdecl xercesc_3_1::AbstractDOMParser::docCharacters(unsigned short const * const,unsigned __int64,bool)"
error LNK2001: unresolved external symbol "public: virtual void __cdecl xercesc_3_1::AbstractDOMParser::docComment(unsigned short const * const)"
error LNK2001: unresolved external symbol "public: virtual void __cdecl xercesc_3_1::AbstractDOMParser::docPI(unsigned short const * const,unsigned short const * const)"
error LNK2001: unresolved external symbol "public: virtual void __cdecl xercesc_3_1::AbstractDOMParser::endElement(class xercesc_3_1::XMLElementDecl const &,unsigned int,bool,unsigned short const * const)"
error LNK2001: unresolved external symbol "public: virtual void __cdecl xercesc_3_1::AbstractDOMParser::ignorableWhitespace(unsigned short const * const,unsigned __int64,bool)"
error LNK2001: unresolved external symbol "public: virtual void __cdecl xercesc_3_1::AbstractDOMParser::startElement(class xercesc_3_1::XMLElementDecl const &,unsigned int,unsigned short const * const,class xercesc_3_1::RefVectorOf const &,unsigned __int64,bool,bool)"
error LNK2001: unresolved external symbol "public: virtual void __cdecl xercesc_3_1::AbstractDOMParser::XMLDecl(unsigned short const * const,unsigned short const * const,unsigned short const * const,unsigned short const * const)"


原因を調べてみたところ、どうやらXercesではWChar_tをBuilt in Typeとして扱わないと使えないみたいでリンクできなかったみたいです。

ということでVisual Studioのプロジェクト設定のC/C++のLanguageからTreat WChar_t As Build in TypeをYesに変更してみました。

wcharSetting.gif
 
これでビルドしてみたらちゃんとリンクされてうまくビルドできました。

同じエラーに遭遇してしまった方は一度これを試してみると解決するかもしれません。

Xerces-C++/DOM XML文書の外部ファイル書き出しサンプル

2011/08/22
Xerces C++のDOMを使った外部ファイルへのXML文書書き出しのサンプルがネット上にあまりなかったので、DOMを使って作成したXML文書を書き出すサンプルコードを載せておきます。

この例ではDOMを使ってparamというタグにnameとvalueというアトリビュートを持たせてパラメータ設定に使えるようなXMLを作成し、そのDOMドキュメントを書き出しています。

動作確認したバージョンはXerces 3.1.1です。

Source Code

#include <iostream>

#include <xercesc/dom/DOM.hpp>
#include <xercesc/framework/LocalFileFormatTarget.hpp>

XERCES_CPP_NAMESPACE_USE

void OutputXML(xercesc::DOMDocument* pmyDOMDocument, const char *filePath)
{
    DOMImplementation *implementation = DOMImplementationRegistry::getDOMImplementation(L"LS");
    DOMLSSerializer *serializer = ((DOMImplementationLS*)implementation)->createLSSerializer();
    if (serializer->getDomConfig()->canSetParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true)){
        serializer->getDomConfig()->setParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true);
    }

    serializer->setNewLine(XMLString::transcode("\r\n"));

    //** Convert the path into Xerces compatible XMLCh*.
    XMLCh *tempFilePath = XMLString::transcode(filePath);

    //** 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();
}

int main()
{
    try{
        XMLPlatformUtils::Initialize();
    }catch(const XMLException& e){
        char* message = XMLString::transcode(e.getMessage());
        fprintf(stderr, "Error during initialization! : %s\n", message);
        XMLString::release(&message);
        return -1;
    }

    char *names[]={"param1", "param2", "param3"};
    char *values[]={"11", "32", "5"};

    DOMImplementation* impl =  DOMImplementationRegistry::getDOMImplementation(XMLString::transcode("Core"));
    DOMDocument* doc = impl->createDocument(0,XMLString::transcode("ParameterSettings"),0);
    DOMElement* rootElem = doc->getDocumentElement();

    //** create child elements
    for(int i=0; i<3; i++){
        DOMElement *elem = doc->createElement(XMLString::transcode("param"));
        elem->setAttribute(XMLString::transcode("name"), XMLString::transcode(names[i]));
        elem->setAttribute(XMLString::transcode("value"),XMLString::transcode(values[i]));
        rootElem->appendChild(elem);
    }

    OutputXML(doc, "sample.xml");

    doc->release();
    XMLPlatformUtils::Terminate();
    return 0;
}



Output XML file

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<ParameterSettings>

  <param name="param1" value="11"/>

  <param name="param2" value="32"/>

  <param name="param3" value="5"/>

</ParameterSettings>

0  

にほんブログ村 ゲームブログ ファイアーエムブレムへ にほんブログ村 デザインブログ コンピュータグラフィックスへ

0.0227 sec

Copyright(C)2006-2018 wsp All Rights Reserved