C,C++でXMLタグを読むには?

解決


ユウ  2006-06-09 18:38:54  No: 62119

XMLファイルを読み込み、ノードのたどり方、データの抽出の仕方をご教授願います。

XMLの例
<AAA>
    <BBB>bbbb</BBB>
    <CCC>
          <DDD>dddd</DDD>
          <EEE>eeee</EEE>
    </CCC>
       ・
       ・
       ・
       ・
</AAA>
 
以下のデータの取得の仕方
bbbb
dddd
eeee

現状ソース

#import "msxml3.dll"
using namespace MSXML2;

typedef MSXML2::IXMLDOMNodeListPtr  INodeListPtr;
typedef MSXML2::IXMLDOMNodePtr    INodePtr;
typedef MSXML2::IXMLDOMElementPtr  IElementPtr;

HRESULT hr;

try{
  //COMライブラリの初期化
  CoInitialize(NULL);

  IXMLHTTPRequestPtr pIXMLHTTPRequest = NULL;
  BSTR bstrString = NULL;

  //HTTPリクエストのインスタンスを生成
  hr = pIXMLHTTPRequest.CreateInstance("Msxml2.XMLHTTP.3.0");
  if(FAILED(hr)){return false;}

  //ドキュメントのインスタンスを作成
  MSXML2::IXMLDOMDocument2Ptr pDoc;
  hr = pDoc.CreateInstance( __uuidof(MSXML2::DOMDocument40) );
  if(FAILED(hr)){return false;}

  pDoc->async = VARIANT_FALSE; 

  //POSTメッセージ作成
  hr = pIXMLHTTPRequest->open(_bstr_t(_T("POST")), _bstr_t(_T(URL)), _variant_t(VARIANT_FALSE));
  if(FAILED(hr)){return false;}

  //POSTメッセージ送信
  hr = pIXMLHTTPRequest->send();
  if(FAILED(hr)){return false;}

  //XMLファイルのロード
  hr = pDoc->load(pIXMLHTTPRequest->responseText);
  if(FAILED(hr)){return false;}

######################################################

  XMLのTAGデータ抽出

######################################################
  // COMライブラリの終了処理
  CoUninitialize();
}catch(...){
}

ご教授よろしくお願いします。


επιστημη  2006-06-09 18:52:59  No: 62120

> 以下のデータの取得の仕方
> bbbb
> dddd
> eeee

これのどこが'取得の仕方'ですか?
単に'取得されたデータ'でしかありません。


ユウ  2006-06-09 20:03:43  No: 62121

質問がおかしかったようで申し訳ありません。
> bbbb
> dddd
> eeee
それぞれ取得されたデータを抽出するために、
ノードのたどっていきたいのですが・・・

以下のページを参考に作成しています。
http://www7a.biglobe.ne.jp/~forte/xml/xmlread.htm

//XMLデータ抽出

//INodeListPtr plaaa = pDoc->getElementsByTagName("AAA");
/*bbbb抽出*/
IElementPtr  peaaa = plaaa->Getitem(0);
IElementPtr  pebbb = peaaa->->getElementsByTagName("BBB")->Getitem(0);
_variant_t   str   = pebbb->Gettext(); 

ddddとeeee抽出はわかっていません・・・よろしくお願いします。


επιστημη  2006-06-09 20:07:55  No: 62122

いや、だから、どんなエレメントを抽出するのか'あなた'が決めてくれないとどーしよーもないんですけど。

再度問います。どんな条件でエレメントを抽出するのですか?


ユウ  2006-06-09 22:38:20  No: 62123

>どんな条件でエレメントを抽出するのですか?
条件というのがよくわからないのですが・・・

<AAA>
    <BBB>bbbb</BBB>
    <CCC>
          <DDD>dddd</DDD>
          <EEE>eeee</EEE>
    </CCC>
</AAA>

XMLファイルが上記の形であるときの
①<BBB>ノードのbbbb要素
②<DDD>ノードのdddd要素
③<EEE>ノードのeeee要素

をアウトプットとした抽出がしたいです。

回答になってないですよね。もう少しXMLの勉強してきます。


dairygoods  2006-06-09 23:50:55  No: 62124

bbbb が抽出できているのだから、
他も同様に取得できませんか。

一階層増えただけでわからなくなってしまったのでしょうか?


ユウ  2006-06-10 01:39:13  No: 62125

>bbbb が抽出できているのだから、
>他も同様に取得できませんか。

上記の抽出ロジックではなにも要素を取り出せていません。

まぎらわしい、質問になってすいません。


επιστημη  2006-06-10 02:14:52  No: 62126

getElementsByTagName(XXX)->Getitem(0);
において、XXX を "BBB","DDD","EEE" にすりゃいいんじゃないですか?


ユウ  2006-06-10 06:05:17  No: 62127

>getElementsByTagName(XXX)->Getitem(0);

これらを使っていますがうまくいきません。

INodeListPtr plaaa = pDoc->getElementsByTagName("AAA");
IElementPtr  peaaa = plaaa->Getitem(0);
/*下の命令で例外処理に行ってしまいます。*/
IElementPtr  pebbb = peaaa->getElementsByTagName("BBB")->Getitem(0);
_variant_t   str   = pebbb->Gettext();


επιστημη  2006-06-10 06:17:34  No: 62128

> IElementPtr  pebbb = peaaa->getElementsByTagName("BBB")->Getitem(0);

あのー…
peaaa->getElementByTagName("BBB")
の意味わかってます?


ユウ  2006-06-10 23:42:06  No: 62129

>あのー…
>peaaa->getElementByTagName("BBB")
>の意味わかってます?

http://www7a.biglobe.ne.jp/~forte/xml/xmlread.htm
前記述でもあげましたが、上記のページを参考に作成しており、自分の解釈としては
INodeListPtr plaaa = pDoc->getElementsByTagName("AAA");
でルートのTAG<AAA>にパスをとり、
IElementPtr  peaaa = plaaa->Getitem(0);
IElementPtr  pebbb = peaaa->getElementsByTagName("BBB")->Getitem(0);
_variant_t   str   = pebbb->Gettext(); 
でTAG<BBB>のデータbbbbを抽出できると考えていました。

以下の違いもよくわかっていません。
MSXML2::IXMLDOMNodeListPtr
MSXML2::IXMLDOMNodePtr
MSXML2::IXMLDOMElementPtr


επιστημη  2006-06-11 01:37:57  No: 62130

------------- foo.cpp ---------

#include <iostream>
#include <string>

#import "msxml6.dll" rename_namespace("msxml")

void run() {

    msxml::IXMLDOMDocumentPtr doc("MSXML.DOMDocument");
    doc->validateOnParse = VARIANT_FALSE;
    doc->load("foo.xml");

    msxml::IXMLDOMElementPtr root = doc->documentElement;
    const char* tagname[] = { "BBB", "DDD", "EEE" };
    for ( int i = 0; i < 3; ++i ) {
      msxml::IXMLDOMNodeListPtr list = root->getElementsByTagName(tagname[i]);
      msxml::IXMLDOMElementPtr element = list->item[0];
      msxml::IXMLDOMTextPtr text = element->firstChild;
      std::string str = static_cast<const char*>(_bstr_t(text->nodeValue));
      std::cout << tagname[i] << " contains " << str << std::endl;
    }
}

int main() {
    if ( FAILED(CoInitialize(0)) ) return 1;
    run();
    CoUninitialize();
    return 0;
}

xmlはファイル foo.xml に書きました


ユウ  2006-06-11 02:12:05  No: 62131

επιστημη さんソースまでのせて頂いてありがとうございました。

データ抽出は解決しました。

以下解決ソースです。

pDoc->load("verifyXmlAction.do.xml");

//resultルート
INodeListPtr plResult = pDoc->getElementsByTagName("result");
IElementPtr peResult = plResult->Getitem(0);

// タグ名"status"の要素を取得
IElementPtr peStatus = peResult->getElementsByTagName("status")->Getitem(0);
_variant_t status   = peStatus->Gettext();

//ccdルート
INodeListPtr plCcd = pDoc->getElementsByTagName("ccd");
IElementPtr peCcd   = plCcd->Getitem(0);

// タグ名"refCode"の要素を取得
IElementPtr peRefCode = peCcd->getElementsByTagName("refCode")->Getitem(0);
_variant_t refCode = peRefCode->Gettext();

// タグ名"completeCode"の要素を取得
IElementPtr peCompCode = peCcd->getElementsByTagName("completeCode")->Getitem(0);
_variant_t compCode = peCompCode->Gettext();

// タグ名"date"の要素を取得
IElementPtr peDate = peCcd->getElementsByTagName("date")->Getitem(0);
_variant_t date = peDate->Gettext();

// タグ名"time"の要素を取得
IElementPtr peTztime = peCcd->getElementsByTagName("time")->Getitem(0);
_variant_t tztime = peTztime->Gettext();

ご教授ありがとうございました。


ユウ  2006-06-11 02:49:54  No: 62132

解決にチェックわすれました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加