Translates an Android string resource file (res/values/strings.xml) into another language and returns the whole XML file, so the Android build and the app accept it. Only the text between the tags changes. Resource names, attributes, comments, placeholders such as %1$s, %d and %%, the escapes backslash-apostrophe, backslash-quote, backslash-n and backslash-at, the quoted form for leading or trailing spaces, inline markup, CDATA sections and the protected spans of xliff:g elements come back exactly as they were. Strings marked translatable="false" are left out. Every plurals block gets exactly the quantity items the target language needs under the CLDR rules, for example one and other for German and Bulgarian, one, few, many and other for Russian, Ukrainian and Polish, six for Arabic and only other for Japanese. A file that is not Android XML, or is cut off, gets a one-line refusal instead of a guess. Use to translate Android strings.xml files, for Android localization of an app, or to add values-de, values-ru or values-ja with the right plural quantity items.
Android Strings Translate: strings.xml That Still Builds is a tested SKILL.md that translates an Android string resource file (res/values/strings.xml) into another language and returns the whole XML file, so the Android build and the app accept it; an agent buys it once for $0.01 over x402.
Not for
Choosing terminology for you, translating iOS Localizable.strings, gettext, JSON or XLIFF files (other skills cover those formats), adding a new language folder to your project, merging with a newer source file, or checking your layouts for text that grows. It translates one resource file per request and does not rename, split or merge files.
Tested, honestly
Tested 2026-10-09 with a strong and a weak model.
With and without the skill
Results with and without the skill, for Sonnet and Haiku |
| with | without | with | without |
|---|
| Android files translated right (22) |
| Android files translated right (22) | 22/22 | 22/22 | 21/22 | 18/22 |
|---|
| Not Android XML or cut off, refused (2) |
| Not Android XML or cut off, refused (2) | 2/2 | 0/2 | 2/2 | 0/2 |
|---|
Same request on both sides: translate this strings.xml, answer with the XML only. Sonnet without the skill already translated every Android file right. It never refuses, because the request does not ask it to: an iOS strings file came back converted to Android XML, and a file cut off mid-element came back cut off the same way. The price rests on the first row. Haiku without the skill missed four there: a Japanese plural block with the English pair copied, unescaped apostrophes in Ukrainian and Italian, and arguments swapped in a reordered Japanese string.
Same cases and the same checks with and without the skill. The cases are ours, written around what the skill is for; with a handful of cases, a difference of one or two is within noise.
- SonnetStrong model, claude-sonnet-5-5
- Right on all 24 files, checked by code on the XML structure: plural items per language (four for Russian and Polish, six for Arabic, one for Japanese), apostrophes escaped in Italian and Ukrainian, quotes, percent signs and whitespace escapes, xliff spans and CDATA kept, translatable="false" strings left out, an ampersand kept escaped, numbered placeholders where the word order changes, comments kept byte for byte, and a CANNOT TRANSLATE line for an iOS strings file and for a file cut off mid-element.
- HaikuWeak model, claude-haiku-5-5
- Right on 23 of 24, checked by code, but in a Japanese string whose word order changes it kept the unnumbered %s and %d in the new order, which swaps the two arguments.
Full test summary
Example
Our own test text, before and after the skill ran. Excerpts only.
English · claude-sonnet-5-5
Before
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Counter in the file picker. -->
<string name="action_save">Save changes</string>
<plurals name="files_selected">
<item quantity="one">%d file selected</item>
<item quantity="other">%d files selected</item>
</plurals>
<plurals name="reports_sent">
<item quantity="one">%d report sent</item>…
After
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Counter in the file picker. -->
<string name="action_save">Сохранить изменения</string>
<plurals name="files_selected">
<item quantity="one">Выбран %d файл</item>
<item quantity="few">Выбрано %d файла</item>
<item quantity="many">Выбрано %d файлов</item>…
What is in the file
- The answer
- What you translate
- What you keep exactly
- Escapes that Android needs
- Placeholders and word order
- Plurals
- Words
- What you refuse
- Work in this order
- Short example
Languages
Any language. Tried in: English.
License
Perpetual, non-exclusive; use and modify for yourself incl. paid work; no resale or republishing. Holder: Georgi Kalchev, aiskills402.com. Full terms.
Versions
Current version 1.0.0, updated 2026-10-09. Whoever bought an earlier version gets new ones free through the same re-download token.
v1.0.0 · 2026-10-09
First release (draft, not yet measured): translates an Android strings.xml and returns the whole file with only the text changed. Resource names, attributes, comments, placeholders, escapes, quoted whitespace, inline markup, CDATA and xliff:g spans are kept; translatable false strings are left out; every plurals block gets the CLDR quantities of the target language; unfit input gets a CANNOT TRANSLATE line. 24 cases (18 traps, 6 controls) checked by the xml check. Price $0.02 proposed; to be set by the measured gain.
FAQ
Which parts of the XML does it touch?
Only the words between the tags. Resource names, attributes, comments, the declaration, the namespace on the root element, inline markup, CDATA sections and every placeholder are returned unchanged, so the app still finds each string and a diff against the old file shows translated text alone. Strings marked translatable false are left out, as Android lint expects. Save the result in the values folder of the target language, such as values-pl. Order and indentation follow your default file, which keeps review simple.
How many plural items does one plurals block get?
Exactly the quantities the target language has under the CLDR rules: one and other for German and Bulgarian, one, few, many and other for Russian, Ukrainian and Polish, six for Arabic and only other for Japanese. The English pair is replaced, not copied. The number placeholder stays in every item that covers more than one number, for example the Russian form for one, which also serves twenty-one. Missing quantities are a lint error and a wrong noun in the app.
What about apostrophes, quotes and percent signs?
Android reads strings through its own escape rules. Every apostrophe you get back is escaped with a backslash, which matters for Italian and Ukrainian where ordinary words contain one. Quotes inside values, backslash n, a leading backslash at sign, leading or trailing spaces kept inside double quotes, a doubled percent sign and formatted false strings all survive. Several placeholders are numbered when the word order changes.
Files that are not Android XML, and the gain for Claude Sonnet?
On Android files, no, hence one cent. Both Claude models translated twenty-two of them into eight languages with the file and again bare, checked by XML structure; plain Sonnet got all of them right, and Haiku rose from 18 to 21. The difference is the refusal: an iOS strings file, a gettext catalog, JSON or a file cut off mid-element gets one CANNOT TRANSLATE line. Without the file Sonnet converted an iOS file to Android XML and returned a cut-off file cut off, as our request did not ask it to stop.