ホーム > X-Plus > XML Square >  デベロッパーズコーナー  >  DOMプログラミング講座

この記事を送る はてなブックマークに追加する BuzzurlにブックマークBuzzurlにブックマーク Yahoo!ブックマークに登録
テキストリンクコードを取得する

デベロッパーズコーナー:DOMプログラミング講座 III(2)-1

2002年02月14日作成 

DOM プログラミングレッスン
第2回:C++ アプリケーションから MSXML を使う(その2)
(株)日本ユニテック
太田 純

<この記事はDigital Xpress 2001 Vol.2(4-5月号)に掲載されたものです>

前回は、MSXML を使用して C++ から DOM を扱うためのプログラミングの準備および概要を扱いました。今回はさらに、高速に処理するための考慮点やエンコーディングに関する話題をお届けしたいと思います。

ツリー構造をたどらずに目的のデータを取り出す

DOM を使用していくにあたって、firstChild, lastChild, nextSibling, previousSibling といったプロパティを使ってツリーをたどるのが基本ですが、ツリーをたどらずに目的のノードを取り出すためのメソッドも用意されています。

リスト1に、XML 文書中の Title 要素の内容を m_strTitle に、Description 要素のサブツリーに含まれるすべてのテキストを m_strDescription に取り出す例を挙げます。この例ではエラー処理は省略しています。

CComBSTR bstrText;
IXMLDOMNodePtr pNode1;
IXMLDOMNodePtr pNode2;
IXMLDOMNodeListPtr pNodeList;
_variant_t varText;

pElemRoot->getElementsByTagName(CComBSTR(L"Title"), &pNodeList); // (A)
pNodeList->get_item(0, &pNode1);
pNode1->get_firstChild(&pNode2);
pNode2->get_nodeValue(&varText);
m_strTitle = varText.bstrVal;

pNode1 = NULL;
pElemRoot->selectSingleNode(CComBSTR(L"Description"), &pNode1); // (B)
pNode1->get_text(&bstrText);
wchar_t *pBuf = new wchar_t[bstrText.Length() * 2 + 1];
wcsLFtoCRLF(pBuf, bstrText); // (C)
m_strEdit1 = pBuf;
delete [] pBuf;
リスト1

リスト1の (A) に示した getElementsByTagName メソッドは、指定した要素名を持つノードのリストを返します。このメソッドは、IXMLDOMDocument および IXMLDOMElement で使用することができ、IXMLDOMDocument の場合は文書全体から、IXMLDOMElement の場合は子孫ノードから指定した要素名のノードを検索し、結果としてコレクションが作られます。メソッドを呼び出す IXMLDOMElement オブジェクト自身が指定したのと同じ要素名を持っていたとしても、自分自身は結果のコレクションには含まれません。

この例には挙げていませんが、selectNodes メソッドも同様にノードのリストを返すメソッドで、第 1 引数には XPath を使用できます。MSXML 3.0 より前のバージョンでは、XPath 1.0 に完全に準拠しているわけではありませんが、XSL と同様のパターン指定 (XSLPattern) が使用できます。MSXML 3.0 は XPath 1.0 に準拠しているようです。

MSXML 3.0 では、以前のバージョンとの互換性を保つために、selectNodes メソッドが使用する文字列はデフォルトでは XPath ではなく、XSLPattern となっています。要素の検索を行うための簡単な指定なら、XPath と XSLPattern に違いはありません。より複雑な検索を行ったり、要素以外のノードを検索する場合は XPath を用いる必要がでてきます。パターン指定を変更するためのメソッド setProperty は、IXMLDOMDocument のメンバではなく、IXMLDOMDocument2 のメンバなのでこれを使うためにはいくつかの変更が必要になります。

  • #import で指定する DLL 名を "msxml.dll" から "msxml3.dll" に変える
  • 使用する namespace 名を MSXML から MSXML2 に変える

ファイルの先頭に以下のようなコードを入れることになるでしょう。

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

このように変更した上で、selectNodes でのパターン指定方法を XPath に変更するには次のように行います。

IXMLDOMDocument2Ptr pDoc2 = pDoc;
pDoc2->setProperty(_bstr_t(L"SelectionLanguage"), variant_t(L"XPath"));

ここで、pDoc は IXMLDOMDocument のポインタです。

リスト1の (B) に示した selectSingleNode メソッドは、selectNodes と同様に XPath または XSLPattern の文字列を使用しますが、指定されたノードのうち最初に見つけたもの 1 つのみを返却します。また、次の行にあるtextプロパティは、前回もご紹介しましたが、そのノード配下にある文字列を連結して返却します。(注1

これらのメソッドを使うと、単にコーディングが簡単になるだけでなく、COM を通してアクセスする回数が減らせる分、高速に処理できるというメリットがあります。

リスト1の (C) にある wcsLFtoCRLF 関数はリスト2のようになっています。

void wcsLFtoCRLF(wchar_t *pDst, const wchar_t *pSrc)
{
    while(*pSrc)
    {
    if(*pSrc == '\n')
        *pDst++ = '\r';
    *pDst++ = *pSrc++;
    }
    *pDst = '\0';
}

ここでは、\n を見つけて、\r\n に変える処理を行っています。DOM から取得される文字列に含まれる改行は、\n のみで示されることになっているため、Edit コントロールなどに文字列を入れる場合にはこの変換が必要となります。

>>次に、MFCアプリケーションへの組み込みと文字コードの変換をしてみましょう。



関連サービス

IT技術およびIT製品の可用性調査・検証業務



この記事と関連の高い記事

関連キーワード:C++


関連キーワード:MSXML


関連キーワード:プログラミング




ページトップへ戻る