将电子表格自动化到strings.xml以进行本地化

时间:2011-11-04 19:33:54

标签: android spreadsheet google-sheets

我有一个谷歌电子表格,其中包含我所有strings.xml资源的翻译。每种语言都是一列。第一列是字符串资源ID。您是否知道我可以使用的工具(或宏或任何东西)可以让我将我的speadsheet重新导出为带有相应区域后缀的strings.xml格式? (后缀是电子表格的第一行)

由于

3 个答案:

答案 0 :(得分:0)

以下是步骤:

  1. 将电子表格导出为打开Office
  2. 解压缩
  3. 获取content.xml文件
  4. 解析和/或翻译
  5. 生成不同的strings.xml个文件
  6. 或者,您可以使用PyUNO从OOo文档中提取内容。

答案 1 :(得分:0)

我提出了一个适用于很多情况的解决方案。你的可能会有所不同。

  1. 我导出为CSV(逗号分隔值)。
  2. 我将CSV导入flash动画中作为文本。
  3. 我通过在新行上分割文本文件将CSV的每一行解析为一个数组。 “\ n” 个
  4. 然后我循环遍历各行,抓住每种语言的价值。
  5. 我的电子表格列标题是

    name,plural value,en,fr,de,it,es,ja
    

    以下是我使用的代码。它有两个缺点,您可能需要应用于您自己的电子表格。首先,它不处理多个值。它只是制作重复的字符串条目,然后您需要返回并手动编辑。其次,如果要翻译的文本包含逗号,则actionscript会将字符串拆分为这些逗号而不是每个部分的末尾。之后我注意到Excel如果包含逗号,则用双引号包装值。但是不确定如果它们包含逗号和双引号会怎么做。如果您的文本有这样的情况,您将需要添加一些代码来处理这些情况。但下面是我使用的Actionscript代码。

    编译并运行swf时,会出现一个黄色按钮。单击它,它将提供保存其中一种语言。每次单击它都会保存不同的语言。如果你继续点击等,它会循环回第一语言。

    但是最终输出应该非常接近完美的翻译strings.xml

    主要类别:

    package 
    {
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.events.MouseEvent;
        import flash.net.FileReference;
        import flash.utils.ByteArray;
    
        /**
         * ...
         * @author Plastic Sturgeon
         */
        public class Main extends Sprite 
        {
            private var rows:Array;
            private var en:XML = <resources></resources>;
            private var fr:XML = <resources></resources>;
            private var de:XML = <resources></resources>;
            private var it:XML = <resources></resources>;
            private var es:XML = <resources></resources>;
            private var xmls:Vector.<XML> = new Vector.<XML>;
    
            private var counter:uint = 0;
            public function Main():void 
            {
                xmls.push(en);
                xmls.push(fr);
                xmls.push(de);
                xmls.push(it);
                xmls.push(es);
    
                if (stage) init();
                else addEventListener(Event.ADDED_TO_STAGE, init);
            }
    
            private function init(e:Event = null):void 
            {
                removeEventListener(Event.ADDED_TO_STAGE, init);
                // entry point
                dumpIt();
                graphics.beginFill(0xFFCC00);
                graphics.drawRect(0, 0, 100, 100);
                stage.addEventListener(MouseEvent.CLICK, onMouseClick);
            }
    
            private function onMouseClick(e:MouseEvent):void 
            {
                var language:int = counter % 5;
                var suffixes:Array = new Array("en", "fr", "de", "it", "es");
                var fr:FileReference = new FileReference();
                var ba:ByteArray = new ByteArray();
                ba.writeObject('<?xml version="1.0" encoding="utf-8"?>\r'+xmls[language].toXMLString());    
                fr.save(ba, "strings-"+suffixes[language]+".xml");
                counter++
            }
            public function dumpIt():void
            {
                var obj:EmbeddedText = new EmbeddedText();
                //txt.text = obj.toString();
                rows = obj.toString().split("\r");
                trace(rows.length);
                for (var i:uint = 0; i < rows.length; i++ ) {
                    var row:Array = String(rows[i]).split(",");
                    for (var j:uint = 0; j < xmls.length; j++ ) {
                        var name:String = row[0]
                        name = name.substring(1);
                        var value:String = row[2 + j];                  
                        var node:XML = new XML('<string name="' + name + '">' + value + '</string>');
                        //trace('<string name="' + name + '">' + value + '</string>');
                        xmls[j].appendChild(node);
                    }
                }
                trace("en",en);
            }
        }
    
    }
    

    用于将文本文件编译为swf的嵌入式文本类:

    package  
    {
        import flash.utils.ByteArray;
    
        /**
         * ...
         * @author Plastic Sturgeon
         */
        [Embed(source="translateion_csv.txt", mimeType="application/octet-stream")]
        public class EmbeddedText extends ByteArray
        {
    
            public function EmbeddedText() 
            {
    
            }
    
        }
    }
    

    最后:这是我翻译的文本的示例,供您自行测试:

    name,plural value,en,fr,de,it,es,ja
    homescreen_new_button,,NEW TOURNAMENT,NOUVEAU TOURNOI,NEUES TURNIER,NUOVO TORNEO,NUEVO TORNEO,
    homescreen_current_button,,VIEW CURRENT BRACKET,VOIR LE TABLEAU ACTUEL,AKTUELLER TURNIERSTAND,VISUALIZZA GRIGLIA,VER NIVEL ACTUAL,
    tournament_type_title,,TOURNAMENT SETTINGS,PARAMÈTRES DU TOURNOI,TURNIER-EINSTELLUNGEN,IMPOSTAZIONI TORNEO,CONFIGURACIÓN DE TORNEO,
    tournament_type_gaming_stations,,HOW MANY GAMING STATIONS,COMBIEN DE POSTES,WIE VIELE SPIELGERÄTE,NUMERO DI POSTAZIONI DI GIOCO,NÚMERO DE MÁQUINAS DE JUEGO,
    tournament_type_tournament_type,,TOURNAMENT TYPE,TYPE DE TOURNOI,TURNIERART,TIPO DI TORNEO,TIPO DE TORNEO,
    tournament_type_tournament_type_single,,SINGLE ELIMINATION,ÉLIMINATION DIRECTE,EINFACHE ELIMINIERUNG,ELIMINAZIONE SINGOLA,ELIMINACIÓN INDIVIDUAL,
    tournament_type_tournament_type_double,,DOUBLE ELIMINATION,DOUBLE ÉLIMINATION,DOPPELTE ELIMINIERUNG,ELIMINAZIONE DOPPIA,ELIMINACIÓN DOBLE,
    tournament_type_back_warning_title,,WARNING,AVERTISSEMENT,ACHTUNG,AVVISO,ATENCIÓN,
    tournament_type_back_warning_message,,Going back to the home screen will clear all information.\nDo you want to continue?,Retourner à l\'écran d\'accueil effacera toutes les données.\nVoulez-vous continuer ?,Durch die Rückkehr zum Home-Bildschirm werden alle Informationen gelöscht.\nWirklich fortfahren?,Tornando alla schermata iniziale perderai tutte le informazioni.\nVuoi continuare?,"Si vuelves a la pantalla principal, se borrará toda la información.\n¿Continuar?",
    tournament_type_back_warning_confirm,,OK,OK,OK,OK,Aceptar,
    tournament_type_back_warning_cancel,,Cancel,Annuler,Abbrechen,Annulla,Cancelar,
    tournament_type_help_single,,Players are eliminated after their first loss.,Les joueurs sont éliminés dès la première défaite.,Spieler scheiden nach ihrer ersten Niederlage aus.,I giocatori vengono eliminati dopo la prima sconfitta.,Los jugadores quedan eliminados a la primera derrota.,
    tournament_type_help_double,,"After a player loses once, they enter the Loser\'s bracket.  They are eliminated if they lose a second time.","Après une première défaite, le joueur intègre le tableau des perdants. Il est éliminé s\'il perd une seconde fois.",Nach einer ersten Niederlage nimmt der Spieler an der Verliererrunde teil. Bei einer zweiten Niederlage scheidet er aus.,"Dopo una sconfitta, i giocatori vengono inseriti nella griglia sconfitti. Vengono eliminati se perdono per la seconda volta.","Al perder una vez, pasan al nivel de perdedores. Si pierden una segunda vez, quedan eliminados.",
    add_players_title,,ADD PLAYERS,AJOUTER DES JOUEURS,SPIELER HINZUFÜGEN,AGGIUNGI GIOCATORI,AÑADIR JUGADORES,
    add_players_seed,,SEED,CLASSER,SETZEN,TESTA DI SERIE,CABEZA DE SERIE,
    add_players_delete,,DELETE,SUPPRIMER,LÖSCHEN,CANCELLA,QUITAR,
    add_players_default_value,,PLAYER NAME,NOM DU JOUEUR,SPIELERNAME,NOME GIOCATORE,NOMBRE DE JUGADOR,
    add_players_dialog_title,,ADD PLAYER,AJOUTER UN JOUEUR,SPIELER HINZUFÜGEN,AGGIUNGI GIOCATORE,AÑADIR JUGADOR,
    add_players_dialog_message,,ENTER THE PLAYER NAME,ENTRER LE NOM DU JOUEUR,SPIELERNAMEN EINGEBEN,INSERISCI IL NOME DEL GIOCATORE,ESCRIBE EL NOMBRE DE JUGADOR,
    add_players_dialog_OK,,OK,OK,OK,OK,ACEPTAR,
    add_players_dialog_ok_and_add,,OK + ADD ANOTHER,OK + EN AJOUTER UN AUTRE,OK + MEHR HINZUFÜGEN,OK + AGGIUNGI ALTRO,ACEPTAR Y AÑADIR OTRO,
    add_players_dialog_cancel,,CANCEL,ANNULER,ABBRECHEN,ANNULLA,CANCELAR,
    add_players_dialog_name_taken,,Name Already Taken,Nom déjà utilisé,Name bereits vergeben,Nome già in uso,Nombre ya utilizado,
    add_players_dialog_name_added,,Player Added,Joueur ajouté,Spieler hinzugefügt,Giocatore aggiunto,Jugador añadido,
    add_players_delete_confirm,,DELETE,SUPPRIMER,LÖSCHEN,CANCELLA,QUITAR,
    add_players_delete_cancel,,DONE,TERMINÉ,FERTIG,FATTO,HECHO,
    

答案 2 :(得分:0)

使用公式=CONCATENATE("<string name=",char(34),A2,char(34),">",E2,"</string>"),其中A2是资源ID,E2是您翻译的语言

复制该列并将其粘贴到您的<resources>_</resources>标记内