RapidXml での空白文字の扱い

RapidXml では,xml_document の parse メソッドに与えるフラグ(テンプレート引数)で空白文字の扱いが変わります.空白文字の扱いに関して定義されているフラグは以下の通り.

const int parse_trim_whitespace = 0x400;
const int parse_normalize_whitespace = 0x800;

parse_trim_whitespace (0x400) を指定すると,テキストに含まれる空白文字 (0x09, 0x0a, 0x0d, 0x20) は全て除去されます.これに対して,parse_normalize_whitespace (0x800) は,テキストに含まれる 1 個以上の連続した空白文字は,1 個の空白文字(ここでの空白文字は,0x20)に置き換えられます.尚,デフォルト (0) を指定した場合は,テキストの空白文字は全て保存されたまま解析されるようです.

・・・のはずなのですが.

以下のような,“空白文字しか存在しないテキスト”が存在する場合に困ったことがありました.

<root>
	<data>         </data>
	<data>fuga</data>
	<data>boke</data>
        
</root>

このプログラムを RapidXML - Life like a clown で作成したサンプルプログラムで解析して出力してみると,以下のような結果が得られました.

[clown@stinger example]$ ./a hoge.xml 
<root>
        <data />
        <data>fuga</data>
        <data>boke</data>
</root>

どうやら“空白文字しか存在しないテキスト”の場合,parse のテンプレート引数に 0(空白文字を保存)をしたとしても読み飛ばされてしまうようです(空白文字 + 他の文字なら大丈夫).これは多分 RapidXml のバグだよなぁと言う事でソースを修正してみました.以下が,修正した diff となります.context 形式の diff は RapidXml@SourceForge.NET に投稿しておいたので,そちらから.

2190a2191,2195
>                         // Text has only whitespace characters (clown, 2009/10/14).
>                         if (contents_start != text && !(Flags & parse_trim_whitespace)) {
>                             parse_and_append_data<Flags>(node, contents_start, contents_start);
>                         }
>                         
2218a2224,2227
>                         
>                         // Skip whitespace between closing-tag of child node
>                         // and the next element (clown, 2009/10/14).
>                         skip<whitespace_pred, Flags>(text);

修正した RapidXml で再度コンパイルを行い,実行した結果は以下の通り.

[clown@stinger example]$ ./a hoge.xml 
<root>
        <data>         </data>
        <data>fuga</data>
        <data>boke</data>
</root>