Android strings xml format specification in Respresso
One of the localization formats that Respresso supports is the commonly used xml used on Android. You can read the Android developers docs page about string resources to learn more about the format.
Currently, Respresso supports only the single string value with proper handling of special characters and full support of variables. Arrays and plurals are not yet supported, but they are hopefully coming soon.
As Respresso is a platform-independent resource management solution, we have no plans to support Android only features like spannables or annotations.
About the format
Android uses multiple resource files in different values
folders that can specify a variety of qualifiers that define when should the app use the resources found in that folder.
Although it is a bad practice, the format allows you to mix all kind of resources (like localizations, colors, dimensions etc.) in a single file.
There is an example how a single strings xml should look like:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="localization_key">localization value</string>
<!--Other string resources-->
</resources>
Requirements of a strings xml:
- Starts with a proper XML declaration. (Like
<?xml version="1.0" encoding="utf-8"?>
.) - The root node must be
resources
. (Make sure that it is opened and also closed.) - Contains some
string
elements in the rootresources
node. - Optionally, it can contain other resource elements and comments, but they might be ignored by Respresso.
Requirements of the string
element:
- Has a
name
attribute. - Contains some text or CDATA.
- Optionally, the
translatable
attribute is also parsed.
How Respresso imports it?
Currently, Respresso can import a single xml file at a time. This is why you have to import it to a preselected language.
When you import an Android resource xml that contains string resources, the following parts will be imported:
- The
name
attribute will be used as a localization key. (It is treated as an id, so it is used to track updates. See import merging strategy.) - The content will be unescaped/decoded and imported as the localization value for the selected language.
- If you selected to import variables, Respresso will parse any printf based variables from the imported localization value and register them with a generated name, similar to
var_1
. - If the
translatable
attribute is present and set tofalse
, then the resource is ignored. - If there is a comment before a string resource element, then it will be imported as a comment. (Except if it contains xml code.)
How Respresso generates it?
Respresso will generate a single xml file for each localization language you add. Optionally, it can output one more for the default language.
Let's assume that you have 3 languages registered in Respresso:
en
(set to be the default language)fr
en-gb
By default, Respresso will generate the following files:
res/values/respresso.strings.xml
(Containing theen
localizations)res/values-fr/respresso.strings.xml
(Containing thefr
localizations)res/values-en-rGB/respresso.strings.xml
(Containing theen-gb
localizations)- Optionally, you can configure it to get an xml file at
res/values-en/respresso.strings.xml
. (Containing theen
localizations)
The last one can be configured in the Flow. See the exportDefaultAsIndividualLanguage option in Flow docs.
The generated files will contain the following:
- A single
string
element for each localization key. - The
name
attribute will contain the transformed localization key. (This ensures key validity.) - Properly escaped localization value in the element's content.
- The localization value will contain transformed localization variable placeholder for each registered variable it contains. (In case it contains multiple variables without attribute indexes the computed argument indexes are automatically included.)
- If there are registered variables a comment will be placed before the string element containing the original name and formatting of the variables.
Let's assume you have a single localization with two registered variables in Respresso:
mainScreen.accountBalance
: Current balance: {{ balance }} ({{ currency }})
It will output a file like this one:
<?xml version='1.0' encoding='UTF-8'?>
<resources>
<!--VARIABLES: balance | %'3.2f; currency | %s-->
<string name="main_screen_account_balance">Current balance: %1$,3.2f (%2$s)</string>
</resources>
Notice:
- The key is transformed to avoid build time errors: camelCase is converted to snake_case, while the
.
is transformed to_
- The original
%'3.2f
variable format is transformed to the Android specific variant with forced argument indexing:%1$,3.2f