Существуют ли какие-либо инструменты для преобразования локализованного строкового файла Iphone в файл строковых ресурсов, который можно использовать в Android?

У меня есть файл с локализованными строками, который используется в приложении Iphone, в котором я работаю для подключения к Android. Есть ли какие-либо инструменты, которые проходят через файл, взятый из проекта xcode, и строят xml, необходимые для использования строк в android?

Поскольку файл apple - это простой файл ключа, есть инструмент, который преобразует строку в этом формате

"ключ" = "значение"

:

<string name="key"> value </string>

Этот инструмент должен быть легко построен, но я ценю любые указатели на уже работающие инструменты.

Ответы

Ответ 1

Хорошо, я написал свой собственный маленький конвертер, немного используя код из alex.

public static void main(String[] args) throws IOException {
    Scanner fileScanner =
            new Scanner(new FileInputStream(args[0]), "utf-16");
    Writer writer =
            new BufferedWriter(new OutputStreamWriter(new FileOutputStream(
                    new File(args[1])), "UTF8"));
    writer.append("<?xml version=\"1.0\" encoding=\"utf-8\"?> <resources>");
    while (fileScanner.hasNextLine()) {
        String line = fileScanner.nextLine();
        if (line.contains("=")) {
            line = line.trim();
            line = line.replace("\"", "");
            line = line.replace(";", "");
            String[] parts = line.split("=");
            String nextLine =
                    "<string name=\"" + parts[0].trim() + "\">"
                            + parts[1].trim() + "</string>";
            System.out.println(nextLine);
            writer.append(nextLine);
        }
    }
    fileScanner.close();
    writer.append("</resources>");
    writer.close();
}

Было немного сложно получить Java, чтобы правильно читать и писать вход UTF 16, который я получил из проекта xcode, но теперь он работает как прелесть.

Ответ 2

Мне кажется, вам может понравиться этот инструмент:

http://members.home.nl/bas.de.reuver/files/stringsconvert.html

Также этот, но ему не хватает некоторых функций (например, конвертация пробелов в имени):

http://localise.biz/free/converter/ios-to-android

Это бесплатно, не требуется регистрация, и вам не нужно будет создавать свои собственные script!

Ответ 3

Это одна из областей, где полезно использовать мышление и набор инструментов Unix. Я не знаю, как выглядит формат iPhone, но если это то, что вы говорите, с каждым значением по одной строке, простой вызов sed мог бы сделать это:

$ cat infile
"key"="value"
"key2"="value2"
$ sed 's/ *"\([^"]*\)" *= *"\([^"]*\)"/<string name="\1">\2<\/string>/' infile
<string name="key">value</string>
<string name="key2">value2</string>
$

Я ожидаю, что sed будет доступен при установке OSX.

Ответ 4

Я улучшил свой основной метод выше, чтобы работать для меня:

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Scanner;

public class StringsConverter {

    public static void main(String[] args) throws IOException {
        Scanner fileScanner = new Scanner(new FileInputStream(args[0]), "utf-16");
        Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(args[1])), "UTF8"));
        writer.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n");
        while (fileScanner.hasNextLine()) {
            String line = fileScanner.nextLine();
            if (line.contains("=")) {               
                String[] parts = line.split("=");

                parts[0] = parts[0].trim()
                    .replace(" ", "_")
                    .replace("\\n", "_")
                    .replace("-", "_")
                    .replace("\"", "")
                    .replace(";", "")
                    .replace("'", "")
                    .replace("/", "")
                    .replace("(", "")
                    .replace(")", "")
                    .replace("?", "_Question");

                parts[1] = parts[1].trim().substring(1, parts[1].length()-3);
                parts[1] = parts[1].replace("'", "\\'");

                String nextLine = "<string name=\"" + parts[0] + "\">" + parts[1].trim() + "</string>";
                System.out.println(nextLine);
                writer.append(nextLine + "\n");
            }
        }
        fileScanner.close();
        writer.append("</resources>");
        writer.close();
    }

}

Ответ 5

"Инструмент", который я использовал для преобразования файла свойств Java:

    BufferedReader br = new BufferedReader(new InputStreamReader(
            new FileInputStream("c:/messages_en.properties"), "utf-8"));
    String line = null;
    while ((line = br.readLine()) != null) {
        line = line.trim();
        if (line.length() > 0) {
            String[] parts = line.split(" = ");
            System.out.println("<string name=\"" + parts[0] + "\">"
                    + parts[1] + "</string>");
        }
    }
    br.close();

Ответ 6

Добавлены несколько модификаций вышеперечисленных решений:

  • Имена строк в стиле Android - нижние регионы, разделенные "_";
  • Преобразование аргументов строкового формата iOS в формат java (% @,% @to% 1 $s,% 2 $s...)
  • Преобразование комментариев;

public static void main(String[] args) throws IOException
{
    Scanner fileScanner =
            new Scanner(new FileInputStream(args[0]), "utf-16");
    Writer writer =
            new BufferedWriter(new OutputStreamWriter(new FileOutputStream(
                    new File(args[1])), "UTF8"));
    writer.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>");
    writer.append("\n");
    while (fileScanner.hasNextLine())
    {
        String line = fileScanner.nextLine();
        if (line.contains("="))
        {
            line = line.trim();
            line = line.replace("\"", "");
            line = line.replace(";", "");
            String[] parts = line.split("=");
            String resultName = processName(parts[0]);
            String resultValue = processValue(parts[1]);
            String nextLine =
                    "<string name=\"" + resultName.toLowerCase() + "\">"
                            + resultValue + "</string>";
            System.out.println(nextLine);
            writer.append(nextLine);
            writer.append("\n");
        } else
        {

            line = line.replace("/*", "<!--");
            line = line.replace("*/", "-->");
            writer.append(line);
            writer.append("\n");
        }
    }
    fileScanner.close();
    writer.append("</resources>");
    writer.close();
}

private static String processValue(String part)
{
    String value = part.trim();
    StringBuilder resultValue = new StringBuilder();
    if (value.contains("%@"))
    {
        int formatCnt = 0;
        for (int i = 0; i < value.length(); i++)
        {
            char c = value.charAt(i);
            char next = value.length() > i + 1 ? value.charAt(i + 1) : '\0';
            if (c == '%' && next == '@')
            {
                formatCnt++;
                resultValue.append('%');
                resultValue.append(formatCnt);
                resultValue.append("$s");
                i++;
            } else
            {
                resultValue.append(value.charAt(i));
            }
        }
    }   else{
        resultValue.append(value);
    }
    return resultValue.toString();
}

private static String processName(String part)
{
    String name = part.trim();
    name = name.replace(" ", "_");
    name = name.replace("-", "_");
    name = name.replace("\n", "_");
    name = name.replaceAll("[^A-Za-z0-9 _]", "");
    if (Character.isDigit(name.charAt(0)))
    {
        name = "_" + name;
    }
    StringBuilder resultName = new StringBuilder();
    for (int i = 0; i < name.length(); i++)
    {
        char c = name.charAt(i);
        if (Character.isUpperCase(c))
        {
            char prev = i > 0 ? name.charAt(i - 1) : '\0';
            if (prev != '_' && !Character.isUpperCase(prev) && prev != '\0')
            {
                resultName.append('_');
            }
            resultName.append(Character.toLowerCase(c));


        } else
        {
            resultName.append(Character.toLowerCase(c));
        }
    }
    return resultName.toString();
}

Ответ 7

Это не отвечает на ваш вопрос, но вы можете подумать о DMLocalizedString для вашего будущего проекта iOS + Android. В настоящее время источник предназначен только для iOS, но я считаю, что сделать версию Android довольно легко.

Ответ 8

Для преобразования в Android используйте код regex. Вы можете протестировать его в Интернете (скопируйте заменяющую строку):

http://www.phpliveregex.com/p/6dA

regex используется ^"(.*)"\s=\s"(.*)";$/m, строка замены <string name="$1">$2</string>

Для преобразования в iOS используйте мой код регулярного выражения (скопируйте заменяющую строку):

http://www.phpliveregex.com/p/6dC

regex используется ^\<string name=\"(.*)\"\>(.*)\<\/string\>/m, строка замены "$1" = "$2";