TinyXML + babelを使ってみる。(1)
TinyXML
babel
C++で作られた各種文字コード( シフトJIS, JIS, EUC, UNICODE(UTF8, UTF16, UTF32) )変換ライブラリです。
以上のライブラリを使って、XMLの実験をします。
最終的にはWPFのXAMLのように、アプリケーションの外観の設定やボタンの配置など出来たらいいなと。
テスト用XML
- test.xml
<?xml version="1.0" ?> <app> <window title="title" w="720" h="480" > <button x="10" y="10" w="100" h="30">ボタン</button> </window> <window title="たいとる" w="320" h="240" /> </app>
まずはチュートリアル通りdumpしてみる
一番下にあるソースをコピペします。
#include "tinyxml.h" // ---------------------------------------------------------------------- // STDOUT dump and indenting utility functions // ---------------------------------------------------------------------- const unsigned int NUM_INDENTS_PER_SPACE=2; const char * getIndent( unsigned int numIndents ) { static const char * pINDENT=" + "; static const unsigned int LENGTH=strlen( pINDENT ); unsigned int n=numIndents*NUM_INDENTS_PER_SPACE; if ( n > LENGTH ) n = LENGTH; return &pINDENT[ LENGTH-n ]; } // same as getIndent but no "+" at the end const char * getIndentAlt( unsigned int numIndents ) { static const char * pINDENT=" "; static const unsigned int LENGTH=strlen( pINDENT ); unsigned int n=numIndents*NUM_INDENTS_PER_SPACE; if ( n > LENGTH ) n = LENGTH; return &pINDENT[ LENGTH-n ]; } int dump_attribs_to_stdout(TiXmlElement* pElement, unsigned int indent) { if ( !pElement ) return 0; TiXmlAttribute* pAttrib=pElement->FirstAttribute(); int i=0; int ival; double dval; const char* pIndent=getIndent(indent); printf("\n"); while (pAttrib) { printf( "%s%s: value=[%s]", pIndent, pAttrib->Name(), pAttrib->Value()); if (pAttrib->QueryIntValue(&ival)==TIXML_SUCCESS) printf( " int=%d", ival); if (pAttrib->QueryDoubleValue(&dval)==TIXML_SUCCESS) printf( " d=%1.1f", dval); printf( "\n" ); i++; pAttrib=pAttrib->Next(); } return i; } void dump_to_stdout( TiXmlNode* pParent, unsigned int indent = 0 ) { if ( !pParent ) return; TiXmlNode* pChild; TiXmlText* pText; int t = pParent->Type(); printf( "%s", getIndent(indent)); int num; switch ( t ) { case TiXmlNode::DOCUMENT: printf( "Document" ); break; case TiXmlNode::ELEMENT: printf( "Element [%s]", pParent->Value() ); num=dump_attribs_to_stdout(pParent->ToElement(), indent+1); switch(num) { case 0: printf( " (No attributes)"); break; case 1: printf( "%s1 attribute", getIndentAlt(indent)); break; default: printf( "%s%d attributes", getIndentAlt(indent), num); break; } break; case TiXmlNode::COMMENT: printf( "Comment: [%s]", pParent->Value()); break; case TiXmlNode::UNKNOWN: printf( "Unknown" ); break; case TiXmlNode::TEXT: pText = pParent->ToText(); printf( "Text: [%s]", pText->Value() ); break; case TiXmlNode::DECLARATION: printf( "Declaration" ); break; default: break; } printf( "\n" ); for ( pChild = pParent->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) { dump_to_stdout( pChild, indent+1 ); } } // load the named file and dump its structure to STDOUT void dump_to_stdout(const char* pFilename) { TiXmlDocument doc(pFilename); bool loadOkay = doc.LoadFile(); if (loadOkay) { printf("\n%s:\n", pFilename); dump_to_stdout( &doc ); // defined later in the tutorial } else { printf("Failed to load file \"%s\"\n", pFilename); } } int main() { dump_to_stdout( "test.xml" ); return 0; }
実行結果
日本語部分は文字化けしてますが、それ以外は当然問題無いですね。
test.xml: Document + Declaration + Element [app] (No attributes) + Element [window] + title: value=[title] + w: value=[720] int=720 d=720.0 + h: value=[480] int=480 d=480.0 3 attributes + Element [button] + x: value=[10] int=10 d=10.0 + y: value=[10] int=10 d=10.0 + w: value=[100] int=100 d=100.0 + h: value=[30] int=30 d=30.0 4 attributes + Text: [繝懊ち繝ウ] + Element [window] + title: value=[縺溘>縺ィ繧犠 + w: value=[320] int=320 d=320.0 + h: value=[240] int=240 d=240.0 3 attributes
UTF-8→シフトJIS変換
TinyXMLは文字コードの変換に対応していないので、今回はbabelを使って変換してみます。init_babel()で初期化してから、utf8_to_sjis()を使って変換します。
#include "babel.h" int main() { babel::init_babel(); ..略.. return 0; }
- テキストノードの取得
std::string str = babel::utf8_to_sjis( pText->Value() );
- 属性の取得
std::string str = babel::utf8_to_sjis( pAttrib->Value() );
実行結果
正しく変換できました。
test.xml: Document + Declaration + Element [app] (No attributes) + Element [window] + title: value=[title] + w: value=[720] int=720 d=720.0 + h: value=[480] int=480 d=480.0 3 attributes + Element [button] + x: value=[10] int=10 d=10.0 + y: value=[10] int=10 d=10.0 + w: value=[100] int=100 d=100.0 + h: value=[30] int=30 d=30.0 4 attributes + Text: [ボタン] + Element [window] + title: value=[たいとる] + w: value=[320] int=320 d=320.0 + h: value=[240] int=240 d=240.0 3 attributes