XULのシングルクォーテーション内にDTDのエンティティを使用するときの注意

ScrapBookをいくつかの特定のロケールで使用している場合に「設定」→「データ保存先」の「参照」ボタンが反応しないという重大なバグが発覚した。原因は、XULのシングルクォーテーション内に埋め込まれたDTDのエンティティにシングルクォーテーションが含まれているため、文法エラーが発生することによる。下記の例をご覧ください。

sample.xul

<button label="Click me!" oncommand="alert('&sample.hello;');" />

sample.dtd

<!ENTITY sample.hello "やあ、'みなさん'こんにちは。">

このとき、シングルコーテーション内で展開されたエンティティ内にシングルコーテーションが含まれるので、以下のような文法エラーとなる。

エラー: missing ) after argument list
ソースファイル: sample.xul
行: 1, 列: 11
ソースコード:
alert('やあ、'みなさん'こんにちは。');

DTDのエンティティ内にどのような文字列が展開されるかは、そのDTDの作成者すなわち翻訳者しだいで予想が付かない。下記のように独自の属性の中にエンティティを埋め込むような回りくどいやり方にしたほうが安全である。

sample.xul

<button label="Click me!"
        oncommand="alert(this.getAttribute('alerttext'));"
        alerttext="&sample.hello;" />

ローカライズ可能な文字列を properties ファイルでなく DTD ファイルで定義するテクニックも今回の件と少し関連しているため、十分に注意が必要である。

TOP

2 Comments to “XULのシングルクォーテーション内にDTDのエンティティを使用するときの注意”

自分の場合は「エンティティ=単に属性値としてのみ使うもの」みたいな固定観念があるので、無意識のうちに「安全なやり方」の方でやっていますね。
この例のようにスクリプトの中に埋め込む使い方についてはむしろ「裏技」みたいな認識だったのですが、このエントリでの指摘を見るまで、問題点に気づいていませんでした。

確かにこれは裏技ですね。何かの拡張機能のソースを見ててこの方法を思いつき、出来るだけpropertiesファイルを作らずにDTDに言語リソースを集約できて便利だと思いきや、思わぬ落とし穴があったというわけです。

TOP

TOP