[ トップ | 一覧 | 更新履歴 ]

VC/COM/DOM

XML | VC

DOM(Document Object Model) XMLをDOMオブジェクトとして扱う

はじめに

3年ほど前に書きかけのまま放置してしまったのと、それ以降VCを触る機会がなくなってるので古いこと書いてある可能性があります。--2006.02.28

DOMはJavaが進んでんのかよく分からないまま、WindowsのVC++で扱ってみます。 XML->DOM->データ抽出までをやってみようかなと。DOMでXMLを作成する方は後まわし。

COMはVisualBasicで簡単に使える(コーディングが簡単)ようになっているようで、 VisualC++で使うには少々困る面があります。

DOMオブジェクトの生成

MSXML.dll

XPathが使えません。

また、MSXML.dllのマイナーバージョンによってはXMLのencodingでのUnicodeへの変換に 対応していないようです。

 encoding="Shift_JIS"

があるとXMLの読込み時にエラーとなります。

bstr

COMとの文字列インターフェースはVB文字列のため、C文字列との変換が必要となり、ピンとこないコードになってしまう。うまくラッピングするなり、工夫が必要。

DOMオブジェクト生成

 #include	<comdef.h>
 #import <msxml.dll> named_guids, raw_interfaces_only
 using namespace MSXML;
 ...
 HRESULT                   hr;
 CComPtr<IXMLDOMDocument>  pXMLDom = NULL;
 ...
     //-------------------------------------
     //  Create DOM document Instance
     //-------------------------------------
     hr = ::CoCreateInstance(
         CLSID_DOMDocument, 
         NULL, 
         CLSCTX_INPROC_SERVER, 
         IID_IXMLDOMDocument,
         (void**)&pXMLDom
     );
     if (FAILED(hr)){
         // エラー処理
     }

MSXML3.dll以降

 #include	<comdef.h>
 #import <msxml3.dll> named_guids, raw_interfaces_only
 //#import <msxml4.dll> named_guids, raw_interfaces_only
 using namespace MSXML2;
 ...
 HRESULT                   hr;
 CComPtr<IXMLDOMDocument>  pXMLDom = NULL;
 ...
     //-------------------------------------
     //  Create DOM document Instance
     //-------------------------------------
     hr = ::CoCreateInstance(
         CLSID_DOMDocument30, //CLSID_DOMDocument40,
         NULL, 
         CLSCTX_INPROC_SERVER, 
         IID_IXMLDOMDocument2, //IID_IXMLDOMDocument3,
         (void**)&pXMLDom
     );
     if (FAILED(hr)){
         // エラー処理
     }

XMLコンテンツをDOMオブジェクトにするまで

DOMオブジェクトへのポインタpXMLDomを使って処理します。

プロパティの設定

put_〜で始まるメソッドは、プロパティの設定を行います。

     //------------------------
     //  DOM Setting
     //------------------------
     hr = pXMLDom->put_async(VARIANT_FALSE);
     if (FAILED(hr)){
         //エラー処理
     }
     hr = pXMLDom->put_validateOnParse(VARIANT_FALSE);
     if (FAILED(hr)){
         //エラー処理
     }
     hr = pXMLDom->put_resolveExternals(VARIANT_FALSE);
     if (FAILED(hr)){
         //エラー処理
     }

XMLをDOMオブジェクトにロード

メモリ上のCの文字列形式から、VBのBSTR形式に変換してロードします。 CString strContentsにXMLの全文が入っているとします。

     //---------------------------------
     //	DOM:Load from text.
     //---------------------------------
 USES_CONVERSION; // A2Tマクロ使用のための前宣言
     _bstr_t str_query(A2T((char*)(LPCTSTR)strContents));
     //--- XML Load.
     hr = pXMLDom->loadXML(str_query, &vbRslt);
     if (FAILED(hr) || vbRslt != VARIANT_TRUE){
         VARIANT_BOOL       vbRslt;
         BSTR               bstr;
         IXMLDOMParseError* pObjError; //XMLの文法解析エラー状態を保存する
         hr = pXMLDom->get_parseError(&pObjError);
         hr = pObjError->get_reason(&bstr);
         _bstr_t str(bstr, false);
         // strにエラー文字列が入っている。エラーハンドリングをここに書くときに使う
         // エラー処理
     }
     BSTR	    bstr = NULL;
     pXMLDom->get_xml(&bstr);

DOMオブジェクトからデータを取得するまで

     CString str_query; //にpathを設定する
     CString str_value; //pathに該当するvalueが入る

値の取り出し方は、Node,Elementを辿って探す方法(下のやり方ではできない)と、pathを指定する方法がある。 XMLが繰り返し構造のときは、pathでは特殊な記述方法となる。(ここでは説明しない)

     AFX_MANAGE_STATE(AfxGetStaticModuleState());
     //--------------------------------
     //  階層を検索する
     //--------------------------------
     CComPtr<IXMLDOMNode>  pNode;
     //
     _bstr_t str_query((LPCTSTR)strQuery);
     hr = pXMLDom->selectSingleNode(str_query, &pNode);
     if (FAILED(hr) || pNode == NULL){
         //エラー処理
     }
     //-------------------------------
     //  値を取り出す
     //-------------------------------
     BSTR    value;
     hr = pNode->get_text(&value);
     if (FAILED(hr)){
         //エラー処理
     }
     _bstr_t str_value(value, false);
     strValue = (char*)str_value;


GzuGzu (WikiWikiWeb descendant) ver 1.00 pre2
このページはGzuGzuで作成されました.
yaino.com