概要
- XMLライブラリのtext取得関数が返す値はライブラリによって意外と違うからちゃんと確認しろ
- XMLのコメントがXMLに何も影響を及ぼさないかというとそんなことはないぞ
前振り
とりあえずこの架空言語で書かれたコードを見てほしい
> parseXML("<a><!---->12<!---->34</a>").element("a").text()
これ何が返ると思う?
- "12"
- "1234"
- ""
実世界の実装では
実装による
xmllint(shellscript)
$ echo '<a><!--x-->12<!--y-->34</a>' | xmllint --xpath 'a/text()' -
1234
rexml(ruby)
> REXML::Document.new("<a><!--x-->12<!--y-->34</a>").elements["a"].text
=> "12"
tinyxml2(C++)
tinyxml2::XMLDocument doc;
doc.Parse("<a><!--x-->12<!--y-->34</a>");
std::cout << doc.FirstChildElement("a")->GetText(); // null
めっちゃざっくりとした解説
- 「コメントは前処理時に消去され、XMLに何ら影響を及ぼさない」というのは必ずしも正しいとは限らない
- text取得関数が何を返すかはライブラリしだい
ライブラリにもよるが、XMLのコメントはコメントノードというものに割り当てられる。
ノードというのは{element, text, comment, その他XML的要素}
の共通抽象的なものだと理解されるとありがたい
文字列 "<a><!--x-->12<!--y-->34</a>"
は
構造 {"a" => [comment("x"),text("12"),comment("y"),text("34")]}
にパースされる
任意のライブラリのtext取得関数は上構造からどうにかして textを返すわけだが
その実装は「最初に見つけたtext」「すべてのtext」「最初のnodeがtextならそれ」「そもそも前処理時にコメントは削除した」などいくつかの可能性が考えられ、つまりライブラリによる
結論
お前のXMLライブラリのtext取得関数が何を返すかちゃんと仕様を確認しろ