Is it possible to do string substitution in Android resource XML files directly?
Asked Answered
D

4

9

In my android app, I have a large string resource xml file. I want to make reference and reuse declared resources values within String values. Is it possible to have the R class resolve referenced values (a la @string/db_table_name)?

<resources>
<string name="db_table_name">tbl_name</string>
<string name="ddl">create table @string/tbl_name</string>
</resources>

Is there a way of doing this. In regular Java world, some tools use ${varname} expression to resolve reference. Can this be done at all in Android?

Dealate answered 13/7, 2011 at 13:17 Comment(1)
you probably dont need your db naming and query creation stuff in xml resources and they will not be dependent on localisation or device qualifiers - I would vote for having this stuff in a global project config file and maybe a static class for query creation - just a thought! Im not aware the above is possible is res files :)Debroahdebs
A
12

Add a %s to your second resource string (the one that you want to be dynamic) where you want it to be modified. i.e.,

<resources>
<string name="db_table_name">tbl_name</string>
<string name="ddl">create table %s</string>
</resources>

and in your code use getString() to work the magic,

getString(R.string.ddl, getString(R.string.db_table_name));
Android answered 13/7, 2011 at 14:17 Comment(1)
I am aware of this approach. I was wondering if the Android tooling would do this when R.java is generated. Using the proposed answer still requires me to do all of the work.Dealate
T
5

It's indeed possible.

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE resources [
  <!ENTITY appname "MyAppName">
  <!ENTITY author "MrGreen">
]>

<resources>
    <string name="app_name">&appname;</string>
    <string name="description">The &appname; app was created by &author;</string>
</resources>

You can even define your entity globaly e.g:

res/raw/entities.ent:

  <!ENTITY appname "MyAppName">
  <!ENTITY author "MrGreen">

res/values/string.xml:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE resources [
    <!ENTITY % ents SYSTEM "./res/raw/entities.ent">
    %ents;   
]>

<resources>
    <string name="app_name">&appname;</string>
    <string name="description">The &appname; app was created by &author;</string>
</resources>
Tamica answered 2/9, 2017 at 19:40 Comment(7)
Hi, I tried this and got "Unresolved Entity Reference" my path is "/raw/entities/ent" because when I set the path to be the same as it written in the example, everything is marked in red and I get "can't find res"Betancourt
I got : Error: The entity "appname" was referenced, but not declared. I did exactly like the exemple, but could get it working...Soapsuds
This solution actually does not work for me: see my question: #50934485Cerveny
@Soapsuds Hi friend! If you found a solution please tell me! :)Cerveny
Are the error you got reported by Android studio? It is possible that Android studio does not support external entities I do not use Android studio myself.... Maybe there is a way to tell Android studio to ignore the "...was referenced, but not declared" error and build anyway. If someone manage to do so report it and I will update my answer.Tamica
@JosephGarrone I think the problem conerns GradleCerveny
This feature was removed from Android Studio.Perlman
H
1

Yes, it is possible without writing any Java/Kotlin code, only XML, by using this small library I created which does so at buildtime: https://github.com/LikeTheSalad/android-stem

Usage

Based on your example, you'd have to set your strings like this:

<resources>
  <string name="db_table_name">tbl_name</string>
  <string name="ddl">create table ${db_table_name}</string>
</resources>

And then, after building your project, you'll get:

<!-- Auto generated during compilation -->
<resources>
  <string name="ddl">create table tbl_name</string>
</resources>
Hygienist answered 7/11, 2019 at 16:41 Comment(0)
B
0

Well, I don't think this is possible. Because once the resources are allocated android won't allow us to change them dynamically in the air. Instead you can try having your Strings in a separate class and change them as you run through your code.

Bedazzle answered 13/7, 2011 at 13:26 Comment(1)
I am not interested in changing the string at runtime, but rather having the code generation of Android that creates the R.java class do the substitution for me at design time. Apparently it is not possible.Dealate

© 2022 - 2024 — McMap. All rights reserved.