Most translators are not engineers, and most translators do not have Android Studio installed. The format they actually want to edit is a two-column spreadsheet — open it in Google Sheets, fill the second column, hand it back. Going from that CSV directly to a strings.xml resource is a recurring chore for any Android team that doesn't pay a TMS to do it, and it's where most home-grown Python scripts produce subtly broken XML: unescaped &, lost apostrophe-escape rules, dotted keys getting mangled, or — worst of all — silently dropped rows when the translator left a value empty.
i18n-convert reads the CSV with the first column as the key and the second column as the value (the convention used by every major translator handoff template), then emits a well-formed strings.xml with <string name="…">…</string> elements for each row. Dotted keys like app.title are kept verbatim — Android allows them inside the name attribute and treats them as opaque identifiers — rather than being silently normalized to underscores. The output is deterministic in row order so that diffs stay reviewable across translation rounds. XML-reserved characters in values are escaped automatically; the file is emitted with the standard <?xml ... encoding="utf-8" ?> prolog and a single <resources> root.
Command
i18n-convert no_comments.csv --to android-xml -o strings.xml
Input
key,en
greeting,Hello
farewell,Goodbye
app.title,My App
Output
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="greeting">Hello</string>
<string name="farewell">Goodbye</string>
<string name="app.title">My App</string>
</resources>