2011/03/03

VC++&MSXMLによるXML操作2




XMLの読込み第2回目


お題目は「C++からMSXMLを初期化、XMLを読み込む」です。



前回の記事には書き忘れましたが、今回以降のサンプルコードはMSXMLに標準で用意されているスマートポインタでラッピングされたクラスを使用していきます。

スマートポインタの使用有無は最終的に開放処理が必要かどうかぐらいのはずなので、お好みでソースコードは改変してください。

また、DLL経由でアクセスします。が、静的ライブラリとは大して違わないと思います。

前もって但し書きしておきます。
このMSXML連載記事の内容は商用でも趣味でも実験でもソースコードはコピーして使用してかまいませんが、記事内の情報を使用して損害、損失、不利益が発生しても、私(管理人)は一切責任を負いません。

なるべく精度の高い情報を載せるように努力はしますが、最終的な確認は使用者本人が行うようお願いします。

後、後始末の処理なんかがよく抜けているので、メモリーリークするコードになっていることが多々ありますし、わざと中略していることもあります。(自慢げにいうことじゃないですが・・・)

さて、前置きが長くなりましたが本題に入りましょう。

MSXMLを使用するにはCOMでアクセス


MSXMLを使用するにはCOMでアクセスしなければなりません。

そのためにはまずはCOMの初期化です。

下記のサンプルでは、まだ定型句みたいなものだと考えてください。

追々説明を追加していきたいとおもいます。


[cpp]
#import "msxml3.dll" named_guids raw_interfaces_only
using namespace MSXML2;

#include <stdio.h>

int main()
{
// COMの初期化
if( FAILED( ::CoInitialize(NULL) ) )
return -1;

HRESULT hr;
VARIANT_BOOL fSuccess;
MSXML2::IXMLDOMDocument2Ptr pDoc;

pDoc.CreateInstance( __uuidof(MSXML2::DOMDocument30) );

pDoc->put_async( VARIANT_FALSE );
pDoc->put_validateOnParse( VARIANT_FALSE );
hr = pDoc->load( _variant_t( "sample.xml" ), &fSuccess );

if ( FAILED(hr) || fSuccess != VARIANT_TRUE)
return -1;

MSXML2::IXMLDOMElementPtr pRoot;
char szText[4096];
bstr_t bstrWork;

pDoc->get_documentElement( &pRoot );
pRoot->get_text( &bstrWork.GetBSTR() );

int size = ::WideCharToMultiByte(CP_ACP, 0, bstrWork, -1, NULL, 0, NULL, NULL) - 1;
::WideCharToMultiByte( CP_ACP, 0, bstrWork, -1, szText, size + 1, NULL, NULL);

printf( "%s", szText );

// 後始末
pDoc.Release();

// COMの後始末
::CoUninitialize();

return 0;
}
[/cpp]

ここまではどこのMSXMLの紹介サイトにも書いてあるサンプルになりました。

(それにしてもC++らしさってものがまったく見られないサンプルだ・・・)

実際XML関連のアプリケーションはここまでできてしまえば後は当てはめていくだけなので、何か紹介しようとしても難しいみたいですね。

次回は各ノードへアクセスしていくためのオブジェクトの紹介を行っていきたいと思います。

おまけ。BSTRとVARIANTの扱い方


BSTRとVARIANTは複数定義しても、全て中身は同じデータになるようです。

つまり、下記の3つのBSTR型のデータは常に一定に見えます。

[cpp]
BSTR bstr1;
BSTR bstr2;
BSTR bstr3;

bstr1 = "sample.xml"

------------------------------------
// 【データの中身】
bstr1 == "sample.xml";
bstr2 == "sample.xml";
bstr3 == "sample.xml";
[/cpp]

これだと、複数定義できないのでSysAllocString等を使ってメモリ確保などを行わないといけないらしいのですが、既に用意されている、bstr_tとvariant_tを使用します。

ちなみにBSTRはデータ型、bstr_tはクラスになっているようです。

扱い方は同じで、BSTR型として扱う場合はGetBSTR()関数を使用すればOKです。

0 件のコメント:

コメントを投稿