私はこのソリューションに従って、文字列リソースファイルでエネティを使用しています。
AndroidリソースXMLファイルで直接文字列置換を行うことは可能ですか?
リソースツリーで外部ファイルを使用しています:/res/raw/entities.dtd
、その内容:
<!ENTITY ent_devicename "MyDeviceName">
の中に string.xml
リソースファイル:
<!DOCTYPE resources [
<!ENTITY % ent_devicename SYSTEM "../raw/entities.dtd">
%ent_devicename;
]>
<resources>
<string name="name">The name is &ent_devicename;</string>
</resources>
しかし、私はこのエラーを受け取ります:
エンティティ「ent_devicename」は参照されましたが、宣言されていません。
ご覧のとおりAndroid Studioは外部エンティティファイルを認識します。
とエンティティ:
誰かが物事を機能させるための完全な正しい例を提供できますか? つまり、完全にコンパイル可能であることを意味しますAndroid Studioプロジェクト、分離されたファイルにエンティティ宣言があります。
[〜#〜] update [〜#〜]OK、このw3schoolsリンクにもっと注意を払えば:
https://www.w3schools.com/xml/xml_dtd_entities.asp
あなたは解決策を見ます:
外部entities.dtd
ファイルには
<!ENTITY ent_devicename "MyDeviceName">
次に、新しい文字列リソースresource:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE resources [
<!ENTITY ent_devicename SYSTEM "../raw/entities.dtd">
]>
<resources xmlns:tools="http://schemas.Android.com/tools" tools:ignore="Typos">
<string name="ent_devicenamxxe2">&ent_devicename;</string>
私が変更され <!ENTITY % ent_devicename
から<!ENTITY ent_devicename
(%以下)削除しました%ent_devicename;
これでコンパイルされますが、結果のAPKはエンティティ値を無視するようです(空の文字列を使用します)。したがって、問題は解決されません!
お知らせ下さい!
TL; DRこの機能はAndroid Studio。から削除されました。バグレポートを参照してください こちら =。
Android Studioで一度にXML外部エンティティがサポートされていたようです。また、Android Studioは現在、エディタ以降、外部エンティティをサポートしているはずです。文句を言わないXMLの基本的な処理は、実際には「参照されているが宣言されていない」エラーを発生させ、期待どおりに組み込みを行いません。
Android Studioが外部エンティティを破棄すること)への明示的な参照は見つかりませんでしたが、発見された脆弱性のため、それは理にかなっています。 XXE攻撃からのデータ露出の影響を受けやすいAndroid開発者 および セキュリティの記述 を参照してください。
外部エンティティへのアクセスがなんらかの理由でゲートされている可能性もありますが、Android Studioがそうである場合、Studioがより役立つと思います。機能が単に削除された可能性が高いです脆弱性に。
ちなみに、私は他の答えを試してみましたが、私には運がありませんでした-同じエラーだけです。
編集:
XXEの脆弱性に対処するJetBrainsについて説明している Medium post に遭遇しました。
2番目の編集
バグトラッカーで無効化の 参照 を見つけました。
これはセキュリティ上の理由で無効になっている可能性があります。解決する前に完全な分析が必要であり、3.2にパントします
そして
これは、セキュリティ上の理由から(XXE攻撃を防止するため)Change-Id:I2f1978bc5458ba2b2b2d6ffbc9df5710c487a4e4で実際に無効になっています。
ステータスは「修正意図の動作ではありません」です。セキュリティ上の理由で機能が無効になっていることを示すエラーメッセージを出力するようにStudioが変更されていたら、良かったでしょう。
この質問への回答/コメントが役に立たないという履歴があるので、一度に簡略化して1ステップずつ近づいていきましょう。以下に示す更新されたエンティティ名を使用し、XMLファイルと含まれているエンティティファイルの両方に単一のディレクトリを使用してください。
string.xml
<!DOCTYPE resources [
<!ENTITY devicename "MyDeviceName">
]>
<resources>
<string name="name">The name is &devicename;</string>
</resources>
これが期待どおりに機能することを確認します。アプリケーションがこのXMLファイルを解析した後、このXMLファイルと同等になるはずです。
<resources>
<string name="name">The name is MyDeviceName</string>
</resources>
手順1を実行できるかどうかをコメントで明示的にお知らせください。
entities.ent
<!ENTITY devicename "MyDeviceName">
string.xml
<!DOCTYPE resources [
<!ENTITY % ext_entities SYSTEM "entities.ent">
%ext_entities;
]>
<resources>
<string name="name">The name is &devicename;</string>
</resources>
準拠するXMLパーサーを使用するXMLアプリケーションにとって、string.xmlは再び以下と同等になります
<resources>
<string name="name">The name is MyDeviceName</string>
</resources>
entities.entで定義されたエンティティを共有できるようになります。
このステップでは、内部エンティティと外部エンティティのエンティティ名を再利用するしないように注意し、複雑さを追加しないでください。別のディレクトリの場所。 entity.entとstring.xmlの両方を同じディレクトリに配置します。 (これは、期待される機能を確立した後で緩和できます。)
繰り返しになりますが、ステップ2を機能させることができるかどうかコメントでお知らせください。
または、Java/Kotlinでプレースホルダーを解決せずにXMLファイルで解決することを好む場合は、私が作成したこの小さなライブラリーを使用できます。 https://github.com/LikeTheSalad/Android-string -reference これにより、次のようなことが可能になります。
<resources>
<string name="devicename">MyDeviceName</string>
<string name="template_name">The name is ${devicename}</string>
</resources>
次に、プロジェクトを作成/ビルドすると、新しいファイルが次のように生成されます。
<resources>
<string name="name">The name is MyDeviceName</string>
</resources>
上記のリポジトリの詳細。