戻り値の時点でエスケープが施されている
Twitter の API 経由で取得したツイート本文のあるデータをたまたま見ていたら、そこに「>(&は半角)」という記述を見つけたので標題のことに気付きました。
同じようなことに気づいた方がいらっしゃいます。
TwitterのAPIの戻り値 htmlエスケープはどうなっているのか記録。 – FNB
上記記事は2014/8/23のものであり、約2年後の現在ではどうなっているかを調べてみました。Twitterはよく仕様が変更されますので。
!"#$%&'()*+,-./:;<=>?@^_`{|}~
以下の文字列が API ではどのように戻ってくるかを調べました。
!"#$%&'()*+,-./:;<=>?@^_`{|}~
すると以下のように戻ってきました(&は半角)。
!"$%&amp;'()*+,-./:;&lt;=&gt;?@[]^_`{|}~
「&」と「<」と「>」(全て半角)がエスケープされている
上記の結果より、「&」と「<」と「>」がエスケープされた状態で生データとして戻ってくることが分かりました。このデータを HTML 上に展開する際はエスケープをかけることになると思いますが、「エスケープがかかったデータにさらにエスケープをかける」ことになってしまいます。
すなわち、「&amp;」にさらにエスケープがかかってしまい「&amp;amp;」になってしまうということです。
生データのエスケープはまずデコードする
戻ってきた生データを何らかの用途でテキストとして用いたい場合はもちろん、HTML上に展開したい場合でも不便です。したがって、戻ってきた生データのエスケープをまず解除する(デコードする)と扱いやすくなると思います。
ただ、DBへの登録の際は、処理の煩雑さや整合性を考えて、生データをそのまま格納しておくほうがよいと思います。DBから取り出したときにデコードをかけて、それから各種文字列の処理を行うのがよいと考えます。
カラムによってエスケープされてたりされてなかったり
このような仕様なので、Twitter の API で戻ってくるテキストデータには一律にエスケープのデコード処理をかけてやれば問題ないし、可読性も高いコードになることが予想されます。
実際結果的にはそれでいいのですが、実はカラムによってはエスケープが行われないカラムもあります。というか、エスケープされるのってツイート本文("text")のカラムだけのような気もします*1。
今後の仕様変更はあり得るのか、またその場合は
このような仕様にしているのは理由があるのでしょうし、そしてまた仕様の変更の可能性は無くはないでしょう。ただしその場合でも、エスケープのデコードを一律にかけていれば(それが面倒だったり煩雑だったりすることは置いといて)、少なくとも、エスケープされたコード混じりの文字列を望まない形で扱うということは避けられると思います。
*1:ちゃんと調べていないので予想です