0
votes

The Android developer docs for string resources show an example string which is also a valid Java variable ("hello_world") which it explains is accessed via R.string.hello_world

My question is whether the XML is permitted to contain string name attributes that are invalid as Java variables. For example, are the following string keys allowed as XML resource names, and if so, how would they be accessed via R.string.<name> in Java?

<string name="hello world" />

<string name="hello.world" />

<string name="42 hello world" />

Note to down-voters: I am not attempting to actually do this. I am attempting to understand what the file format allows and how the resources are converted.

Some context for what and why I'm asking:

My software converts key/value pairs to XML resources and automatically converts all keys to valid Java variables, so "hello-world" is converted to "hello_world". However a user reported that they wanted to keep "hello.world" as the value of XML name attribute. They informed me that the Android builder would convert it to "hello_world". So I am asking this question to work out which cases I should automatically handle and which I should allow through.

2
The real question here is: "Why would you want to do that?"323go
I can clearly see that it is not good practice. You've jumped to a conclusion that want to achieve is wrong. I've updated my question with some context as to what I actually am trying to achieve.Tim
I suppose you might still be missing some context. What does your user have to do with xml attributes? Is it a user of an app, or a library?323go
It is an app - a file format converter. The XML attribute I refer to is the "name" attribute in the string element <string name=".."> I incorrectly typed "key" in my question, which I've now fixedTim
Now it makes more sense. Your XML attributes can contain any valid UTF-8 if escaped properly. Now, if your users take that xml and try to use it as strings.xml, then the Android builder will cough or have some fun with it. There's just no way around that.323go

2 Answers

1
votes

It is not possible. Xml files are parsed and the static class R is generated and, in order to compile, the class has to contain valid members name.

0
votes

I'm answering my own question because although the advice here about best practice is valid, it was not best practice that I asked about.

The answer is that although the string named "hello.world" would be an invalid Java variable, it is permitted in the XML as the build process automatically converts the "." symbol to an underscore before it becomes a Java class member variable.

The following strings:

<string name="foo_bar"> .. </string>
<string name="foo.baz"> .. </string>

Will produce (whether due to a feature or a bug) members in R.java as follows:

public static final class string {
    public static final int foo_bar=0x7f0a000f; // <- valid
    public static final int foo_baz=0x7f0a0010; // <- valid (CONVERTED)
}

The following two strings however:

<string name="foo_bar"> .. </string>
<string name="foo.bar"> .. </string>

Will result in a collision and the build process will fail:

public static final class string {
    public static final int foo_bar=0x7f0a000f; // <- valid
    public static final int foo_bar=0x7f0a0010; // <- DUPLICATE
}

The following strings:

<string name="foo bar"> .. </string>
<string name="foo-baz"> .. </string>
<string name="42foo"> .. </string>

Will break the build process producing invalid members in R.java as follows:

public static final class string {
    public static final int 42foo=0x7f0a0000;   // <- invalid
    public static final int foo bar=0x7f0a000f; // <- invalid
    public static final int foo-baz=0x7f0a0010; // <- invalid
}

I verified these by building a project via Android Studio and also via the command line Gradle program. The "." => "_" conversion appears to be a one-off (although I only tried a few common punctuations as shown above.


TL;DR
Names should be valid Java variables, but the XML format and build process will automatically convert "." symbols adding the risk of key collisions.