Skip to main content
Version: 3.x.x

Android Resources XML

Android resource XML files (usually strings.xml) store localization (i18n) data for Android applications. It supports plurals and arrays. To read more about the Android Localization in general, read the official Android Documentation.

Example

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="user_settings_password_label">
Password
</string>
<plurals name="dogs_count">
<item quantity="one">%d dog</item>
<item quantity="other">%d dogs</item>
</plurals>
<string-array name="string_array">
<item>First item</item>
<item>Second item</item>
</string-array>
<string name="with_xliff_gs">
<b>Hello! <xliff:g>%d</xliff:g></b>
<xliff:g>Don't translate this</xliff:g>
</string>
</resources>

File structure

The Android XML file is an XML-based file with these elements:

  • resources
    • the root element of the file; It doesn't contain any valuable information.
  • string
    • a simple string value.
  • plurals
    • a string that has different forms based on the quantity
    • attributes:
      • quantity: the plural keyword

        Possible keywords: zero, one, two, few, many, other.

        Get the full list of the keywords for each language here. //: # (@formatter:on)

The MessageFormat and placeholder conversion

When importing data to Tolgee from the Android XML files, you can either enable or disable the conversion to the Tolgee Universal ICU placeholders. The conversion is enabled by default. You can also disable the conversion globally in project settings by disabling the Use Tolgee Universal ICU placeholders option. We recommend keeping the conversion enabled, as it brings many benefits. Read more about the benefits of Tolgee Universal ICU placeholders.

When the conversion is disabled, the original placeholders like %s, %d etc. are preserved.

Placeholder conversion specification

The Java documentation about format specifiers can be found here

Only specifiers specified in the table below are supported. Tolgee doesn't support additional flags and modifiers and placeholders using them are not converted.

SpecifierICU typeExampleConverted to ICUNote
%N/A%%%%% is the way how to render %, in ICU we don't have such concept, so we just add %. When exporting, the % is converted back to %%.
snone%s{0}
dnumber%d{0, number}
fnumber, [precision string]%f{0, number, 0.000000}By default %f uses 6 decimal places, that's why we convert it to the number with such precision. %.2 f would be {0, number, 0.00} and so on.
enumber, scientific%e{0, number, scientific}%E is not supported
Java also supports n$ positional specifiers. They are converted to the zero-based argument index. E.g. I am %2$@, and I have %1$lld dogs. is converted toI am {1} and I have {(0, number)} dogs.

Exporting

When exporting the data back to the .xml file, the placeholders are converted back to the original format.

Using with Tolgee Android SDK

When you integrate these XML resources with the Tolgee Android SDK:

  • Resource key mapping: the SDK derives keys from Android resource IDs using resources.getResourceEntryName, so ensure the same keys exist in your Tolgee project.
  • Formatter compatibility: Android XML typically uses printf-style placeholders (e.g., %s, %d). The Android SDK defaults to Sprintf formatting but can be switched to ICU if your data uses Tolgee Universal ICU placeholders.
// Example SDK formatter configuration
Tolgee.init {
contentDelivery {
// Sprintf is default for Android-style placeholders
format(Tolgee.Formatter.Sprintf)
// Or use ICU if your data is in ICU format
// format(Tolgee.Formatter.ICU)
}
}

See also:

Array support

When importing data to Tolgee from the Android XML files, the array elements are converted into flat keys with arrayName[index] format.

For example, the following XML:

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string-array name="string_array">
<item>First item</item>
<item>Second item</item>
</string-array>
</resources>

will be imported to Tolgee as

{
"string_array[0]": "First item",
"string_array[1]": "Second item"
}

and vice versa when exporting from Tolgee to the Android XML file.

Since the [ and ] characters are not allowed in the key names in the Android XML files, there should be no conflicts if you use the Tolgee project only for the Android app. Otherwise, remember that keys named with the described syntax are converted to arrays.

Strings wrapped with CDATA

When Tolgee imports the Android XML file, it extracts the strings from the CDATA sections. e.g. <string><![CDATA[Hello]]></string> is imported as Hello. Keys with imported translations with CDATA-wrapped values are marked with _androidWrapWithCdata custom value. When exporting, keys marked with _androidWrapWithCdata are wrapped with CDATA.

This happens because the main goal of Tolgee is to enable users to use the same translation data on multiple platforms (e.g., Web, Android, Apple). So we have to strip all the additional syntax, which is removed by the Android parser, so we work with a value similar to what Android resource tooling methods return.

However, when Tolgee removes this syntax, without the androidWrapWithCdata custom value, it wouldn't be able to build Android XML resource file without possibly breaking the Android App.

What can go wrong? The Android methods context.resources.getString and context.resources.getText behave differently. context.resources.getString strip all tags and return only the inner text of all nested elements. When we want to use getString together with tags, we have to wrap them with CDATA and handle the HTML manually. On the other hand, context.resources.getText enables us to use some HTML tags in the string and returns SpannedString, which contains information about styling or links.

Now, consider a string <string><![CDATA[Welcome <b>user</b>]]></string>. It is wrapped with CDATA and contains a <b> tag. In our Android app, we use context.resources.getString to get the string that returns Welcome <b>user</b>, and then we use Html.fromHtml to parse the HTML.

Tolgee imports this string as Welcome <b>user</b>. If we exported this string without the CDATA as <string>Welcome <b>user</b></string>, the context.resources.getString would return Welcome user. This means that the user won't be bold anymore in our app.

Escaping and HTML Tag Handling

Character Escaping

When importing data Tolgee unescapes escaped quote \", apostrophe \', backslash \\, new line \n and tab (\t) characters. When exporting, these characters are escaped back. e.g. \" is imported as " etc. Other characters (e.g. escaped unicode characters like \u0020) are not unescaped.

HTML Tag Escaping Behavior

Tolgee handles HTML tags differently depending on the content and context of your strings. Understanding this behavior is crucial for proper Android XML exports:

When HTML Tags Are Escaped

HTML tags like <b>, <i>, etc. are escaped (converted to &lt;b&gt;, &lt;i&gt;, etc.) in the following situations:

  1. Strings containing special XML characters: If the string contains characters that require XML escaping (like & ampersand), the entire string including HTML tags will be escaped to maintain valid XML structure.

  2. Strings with unclosed or malformed HTML tags: To prevent invalid XML output, strings with incomplete HTML structures are fully escaped.

Example of escaped output:

<string name="example_escaped">&lt;b&gt;Free&lt;/b&gt; inquiry &amp; referral to selected companies</string>

When HTML Tags Are NOT Escaped

HTML tags remain unescaped in these cases:

  1. Simple HTML formatting: When the string contains only supported HTML tags without special XML characters.
  2. CDATA wrapped content: Strings marked with _androidWrapWithCdata custom value preserve HTML tags within CDATA sections.

Example of unescaped output:

<string name="example_unescaped">
<b>Receive non-binding</b>
offers
</string>

Inconsistent Escaping - Known Issues

You may encounter situations where similar strings are handled differently:

  • Some strings with HTML tags get properly escaped: &lt;b&gt;Text&lt;/b&gt;
  • Similar strings remain unescaped: <b>Text</b>
  • Line breaks may be unexpectedly added to some exported strings

This inconsistent behavior can occur due to:

  • Presence of special characters (like &) in some translations but not others
  • Different input methods (manual entry vs. import)
  • Automatic CDATA wrapping decisions based on content analysis

Troubleshooting HTML Escaping Issues

Common Problems and Solutions

Problem: HTML tags are not rendering correctly in your Android app

Solutions:

  1. Check your Android rendering method:

    • Use context.resources.getText() for HTML-formatted strings (returns SpannedString)
    • Use context.resources.getString() with Html.fromHtml() for manual HTML parsing
  2. Verify CDATA wrapping: Check if your key has the _androidWrapWithCdata custom value set:

    • If present and causing issues, try removing it
    • If absent and you need CDATA wrapping, add it manually
  3. Consistent formatting: Ensure similar strings are handled consistently:

    • Avoid mixing special characters (like &) with HTML tags when possible
    • Use consistent input methods for similar content types

The escapeHtml Parameter Limitation

Important: The escapeHtml parameter in export requests only applies to XLIFF format exports, not Android XML. Adding escapeHtml=true to your Android XML export URL will have no effect on the output.

Example - This parameter has no effect on Android XML:

/export?format=ANDROID_XML&escapeHtml=true  # escapeHtml ignored for Android XML

For Android XML exports, escaping behavior is determined automatically based on content analysis as described above.

Multiple spaces and quoting

Since XML normalizes white spaces when parsing, Android enables us to preserve longer space sequences by wrapping them into quotes. e.g. <string name="long_space">" "</string>. When importing data to Tolgee, the quotes are removed, and the spaces are preserved.

When exporting the data back to the Android XML file, the longer space sequences are wrapped with quotes unless the string contains XML tags. To preserve whitespaces in strings with XML tags, you can escape them as Unicode characters \u0020.

Importing keys with tags

Unless the string is wrapped with CDATA, tags unsupported by Android are removed when importing data to Tolgee.

The supported tags are the following as stated in the official Android documentation:

b, i, cite, dfn, em, big, small, font, tt, s, strike, del, u, sup, sub, ul, li, br, div, p, a

Tags and Placeholders

When the value contains XML tags and placeholders at the same time, it's always wrapped with CDATA when exported.

Importing / Exporting in general

To read more about importing and exporting with Tolgee, continue to import section or export section.