先日、SeleniumでXpathを使って特殊記号を使った文字列の検索に嵌まったことを書いたが、今度はAndroidアプリの名前にシングルクォート(アポストロフィ)を使おうとして嵌まってしまった。
何が問題だったかと言えば、Androidアプリでアプリの名称やホーム画面に表示されるアイコン下のキャプションを設定するには app/src/main/res/values/strings.xml
に値を設定するわけだが、ここにXMLでの文字参照(エンティティ参照)のルールに従ってエスケープ処理して値をセットしてみる。
ちなみに設定したい文字列は前回のSeleniumの時と同じく “May'n ちゃん "Love" & <1>
” という文字列です。
<string name="app_name">May'n ちゃん "Love" & <1></string>
ところがこの文字列リソースをコンパイルしようとすると以下の様にエラーになってしまう。
..../app/build/intermediates/data-binding-layout-out/debug/values/values.xml:XXX: error:
Apostrophe not preceded by \ (in May'n ちゃん "Love" & <1>)
そこで注意された様にシングルクォート(アポストロフィ)は文字参照のルールに従ってエスケープした上に更にバックスラッシュでエスケープするとエラーは出なくなる。
<string name="app_name">May\'n ちゃん "Love" & <1></string>
という罠…
実は、この罠には続きがあってシングルクォート(アポストロフィ)だけではなくてダブルクォートの方にも罠が仕掛けられていて、ダブルクォートを単純に "
でエスケープすると何故か摩訶不思議な変換を行われてしまい、文字列が予期せぬ場所で途切れたりとエラーは出ないまでも思った通りの結果にはなってくれない。
これはどうやらユーザーによって記述されたリソース情報のXMLファイル中の情報を集めて一つの中間ファイルvalues.xml
を作るらしいのだけど、この時に一旦エスケープされた文字が展開されてしまうらしく、この展開された文字列が含まれるXMLファイルをさらに解析処理しようとした際にエラーとなってしまうらしい。
<string name="app_name">May\'n ちゃん $quot;Love" & <1></string>
で、結局ダブルクォートを文字列に入れたいときはどうするか?というと、以下の様に "
でエスケープするのではな \"
(バックスラッシュとダブルクォート)でエスケープすると大丈夫らいです。
<string name="app_name">May\'n ちゃん \"Love\" & <1></string>
上記のように strings.xml
に値を記述しておけば、それは以下のように展開され、これが更に解析された結果期待した文字列が得られるようです。
それでも未だ数字の 1
の後の >
の処理とかに一抹の不安を覚えるのですが…
<string name="app_name">May\'n ちゃん \"Love\" & <1></string>
誰か、この辺りの正しい記述方法や正式なドキュメントの在り処をご存知ないでしょうか?