• 追加された行はこの色です。
  • 削除された行はこの色です。
#author("2016-07-13T10:31:38+00:00","","")
#author("2017-01-25T01:18:10+00:00","","")
*TinyXML2を使ってみる [#db6cb9ef]
ダウンロード先
https://github.com/leethomason/tinyxml2/issues/37

***XMLパーサーについて [#n6c87057]
XMLにかかれてあるデータ構造を自分できっちりしっていないと、そのデータにたどり着くことができないので、XMLを読み込んだらなんかいい感じにデータにアクセスできるようになることは「ない」
XMLにかかれてあるデータ構造を自分できっちりしっていないと、そのデータにたどり着くことができないので、XMLを読み込んだらなんかいい感じにデータにアクセスできるようになることはない。

コツとしては自分の作ったXMLフォーマットのデータを読み込むのを便利にしてくれるダケのものというイメージでいたほうが良い。実際<>で括られたテキストをパースするのはとても面倒なので、それだけでありがたいモノ。それ以上のことを期待してはいけない。

サーバーから出力される情報を読み取ったりするのに便利

以下、インストールして使うところまで。

*error C2872: 'XMLDocument': あいまいなシンボルです。 [#xa45701d]
ソースをダウンロードしてきて、gxLibと同じフォルダに「tinyxml2.cpp」「tinyxml2.h」を配置してコンパイルする。びっくりするほど簡単だが、なぜかエラーが発生。Win32環境では「WIN32_LEAN_AND_MEAN」の定義がないと不都合があるようなので、ソースの一番最初かプリプロセッサに以下を定義するとコンパイルは通る。

 #define WIN32_LEAN_AND_MEAN

***XMLファイルの読み込み [#mf9b217a]
 tinyxml2::XMLDocument xml;
 xml.LoadFile( "test.xml" );

***XMLファイルを文字列から読み込み [#hbffce91]
 const char * pXMLdoc = "<title>Test Title</title>";
 tinyxml2::XMLDocument xml;
 xml.Parse( pXMLdoc );

***データへのアクセス[#v3bba5eb]
これで取得できる
 XMLElement* root = xml.FirstChildElement( データ名 );

「dir1/data1/」に対してコレはダメ(親ノードをすっ飛ばしてる)
XMLデータ
 <dir1>
 <data1>データ</data1>
 <data2>データ</data2>
 </dir1>
 
 ソースコード
 XMLElement* root = xml.FirstChildElement( dir1 );

とりあえず手持ちのXMLに定義されているしょっぱなのノード名(dir1)を確認して、これで取得できる。ただしXML側の「dir1/data1/」に対して以下の様な記述はダメ(親ノードをすっ飛ばしてる)
 XMLElement* root = xml.FirstChildElement( "data1" );

コレもダメ(パスは繋げない)
 XMLElement* root = xml.FirstChildElement( "dir1/data1" );

これはOK
 XMLElement* dir1 = xml.FirstChildElement( "dir1" );

これが正しい
 XMLElement* data1 = dir1.FirstChildElement( "data1" );
 XMLElement* data1 = root ->FirstChildElement( "data1" );

***データの取得 [#k358f118]
基本的に全てテキストで得られる。データがないもの(ディレクトリなど)はNULLが返る
 const char* txt = data1->GetText();

***次のデータを得る [#n3bc6ba5]
例のXML
複数のデータがある場合には、NextSiblingElementを使って取得する。

XML
 <food>
   <fruits>
      <data>りんご<data>
   </fruits>
 
   <fruits>
      <data>めろん<data>
   <fruits>
 </food>

プログラム
 XMLElement* food   = xml.FirstChildElement( "food" );
 XMLElement* fruits = food->FirstChildElement( "fruits" );
 
 fruits->NextSiblingElement( "fruits" );
 fruits = fruits->NextSiblingElement( "fruits" );
 gxLib::DebugLog( "%s" , fruits->GetText() );

結果
 めろん

こうする。「フルーツ」が自分自身のポインタをつかって次の「フルーツ」を探すイメージ
こうする。「フルーツ」が自分自身のポインタをつかって次の「フルーツ」を探すイメージ。NextSiblingElementでNULLが返ってくるまではデータがある。

 while( gxTrue )
 {
  fruits = fruits->NextSiblingElement( "fruits" );
  if( fruits == NULL ) break;
  gxLib::DebugLog( "%s" , fruits->GetText() );
 }