开发者

Are there any tools to convert an Iphone localized string file to a string resources file that can be used in Android? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers. 开发者_如何学C

We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.

Closed 3 years ago.

Improve this question

I have the localized strings file that is used in the Iphone app that I work on to port to Android. Are there any tools that go through the file taken from the xcode project and build the xml needed to use the strings in android?

As the apple file is a simple key value file is there a tool that converts string in this format

"key"="value"

to this:

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

This tool should be easy to build but I appreciate any pointers to already working tools.


I think you might like this tool :

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

Also this one, but it lacks some features (like converting whitespace in name) :

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

It is free, no need of registration, and you won't need to build your own script!


This is one of the areas where the Unix mindset and toolset comes in handy. I don't know what the iPhone format is like, but if it's what you say, with each value one per line, a simple sed call could do this:

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

I expect sed is available on your OSX install.


Ok i wrote my own little converter using a little bit from the code from 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();
}

It was a little bit tricky to get Java to correctly read and write the UTF 16 input I got out of the xcode project but now it is working like a charm.


I improved your main method above to work for me:

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();
    }

}


The "tool" I've used to convert a Java properties file:

    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();


Added few modification to above solutions:

  • Android styled string names - lowercase worlds, separated by "_";
  • Convert iOS string format arguments to java format (%@, %@ to %1$s, %2$s ...)
  • Convert comments;

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();
}


This don't really answer your question, but you may consider DMLocalizedString for your future iOS+Android project. Currently the source is for iOS only, but I believe that making the Android version is pretty easy.


For converting to Android, use my regex code. You can test it online (copy the replacement string):

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

regex used is ^"(.*)"\s=\s"(.*)";$/m , replacement string is <string name="$1">$2</string>

For converting to iOS, use my regex code (copy the replacement string):

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

regex used is ^\<string name=\"(.*)\"\>(.*)\<\/string\>/m , replacement string is "$1" = "$2";


Web based online converter (both ways): https://gunhansancar.com/tools/converter/

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜