2011-01-08 19 views
20

Qualcuno sa di una libreria Java che mi consente di analizzare i file .PO? Voglio semplicemente creare una mappa di ID e valori in modo da poterli caricare in un database.Esiste una libreria Java per analizzare i file PO gettext?

+0

Che cosa avete bisogno fare? –

+0

Curioso, che cos'è un file PO? – Nishant

+3

un file PO è un file di risorse generato da GNU gettext –

risposta

10

Secondo Java gettext utilities Manual Si può convertire file PO a una classe ResourceBundle utilizzando msgfmt --java2 programma e leggerlo con java.util.ResourceBundle o gnu.gettext.GettextResource - suppongo che sia un modo più efficiente. Gettext-commons fanno esattamente lo stesso compresa la creazione di processo intermedio di chiamare msgfmt perché è posizionato come segue:

Gettext Commons è libreria Java che fa uso di GNUutility gettext.

Se si desidera esattamente una libreria Java, l'unico modo che vedo è scrivere la propria libreria per analizzare questo formato, cioè riscrivere il codice sorgente msgfmt da C a linguaggio Java. Ma non sono sicuro che sarà più veloce di creare il processo + eseguire il programma C.

+2

Ho anche provato la stessa cosa, potresti dirmi come posso usare esattamente "msgfmt" nel mio progetto java per convertire po a ResourceBundle. Sembra un comando. –

4

gettext-commons è l'unico che ho trovato facendo qualche ricerca qualche tempo fa.

+0

Non sono riuscito a trovare il codice in quel progetto che effettivamente legge i file PO. Hai fatto? –

+1

Gettext-commons chiama msgfmt come un passaggio intermedio, quindi non è possibile evitare una creazione di processo. Vedi questa figura http://xnap-commons.sourceforge.net/gettext-commons/gettext-structure.png – aponomarenko

9

Ho cercato su Internet e non sono riuscito a trovare una libreria esistente. Se usi Scala, è abbastanza semplice scrivere un parser tu stesso, grazie alla sua funzione di combinatore di parser.

Chiama PoParser.parsePo("po file content"). Il risultato è un elenco di Translation.

Ho fatto questo codice in una libreria (può essere utilizzato da tutte le lingue JVM, tra cui Java, ovviamente!): https://github.com/ngocdaothanh/scaposer

import scala.util.parsing.combinator.JavaTokenParsers 

trait Translation 

case class SingularTranslation(
    msgctxto: Option[String], 
    msgid: String, 
    msgstr: String) extends Translation 

case class PluralTranslation(
    msgctxto: Option[String], 
    msgid:  String, 
    msgidPlural: String, 
    msgstrNs: Map[Int, String]) extends Translation 

// http://www.gnu.org/software/hello/manual/gettext/PO-Files.html 
object PoParser extends JavaTokenParsers { 
    // Removes the first and last quote (") character of strings 
    // and concats them. 
    private def unquoted(quoteds: List[String]): String = 
    quoteds.foldLeft("") { (acc, quoted) => 
     acc + quoted.substring(1, quoted.length - 1) 
    } 

    // Scala regex is single line by default 
    private def comment = rep(regex("^#.*".r)) 

    private def msgctxt = "msgctxt" ~ rep(stringLiteral) ^^ { 
    case _ ~ quoteds => unquoted(quoteds) 
    } 

    private def msgid = "msgid" ~ rep(stringLiteral) ^^ { 
    case _ ~ quoteds => unquoted(quoteds) 
    } 

    private def msgidPlural = "msgid_plural" ~ rep(stringLiteral) ^^ { 
    case _ ~ quoteds => unquoted(quoteds) 
    } 

    private def msgstr = "msgstr" ~ rep(stringLiteral) ^^ { 
    case _ ~ quoteds => unquoted(quoteds) 
    } 

    private def msgstrN = "msgstr[" ~ wholeNumber ~ "]" ~ rep(stringLiteral) ^^ { 
    case _ ~ number ~ _ ~ quoteds => (number.toInt, unquoted(quoteds)) 
    } 

    private def singular = 
    (opt(comment) ~ opt(msgctxt) ~ 
    opt(comment) ~ msgid ~ 
    opt(comment) ~ msgstr ~ opt(comment)) ^^ { 
    case _ ~ ctxto ~ _ ~ id ~ _ ~ s ~ _ => 
     SingularTranslation(ctxto, id, s) 
    } 

    private def plural = 
    (opt(comment) ~ opt(msgctxt) ~ 
    opt(comment) ~ msgid ~ 
    opt(comment) ~ msgidPlural ~ 
    opt(comment) ~ rep(msgstrN) ~ opt(comment)) ^^ { 
    case _ ~ ctxto ~ _ ~ id ~ _ ~ idp ~ _ ~ tuple2s ~ _ => 
     PluralTranslation(ctxto, id, idp, tuple2s.toMap) 
    } 

    private def exp = rep(singular | plural) 

    def parsePo(po: String): List[Translation] = { 
    val parseRet = parseAll(exp, po) 
    if (parseRet.successful) parseRet.get else Nil 
    } 
} 
+0

Grande, +1 per l'utilizzo di Scala –

2

Il tennera project on github contiene un parser ANTLR-based per GNU Gettext PO/POT. Penso che sia usato da Redhat per un software di traduzione basato sul web.

2

.MO parser (non Java, ma Scala), analizza in mappa: http://scalamagic.blogspot.com/2013/03/simple-gettext-parser.html, fonte: http://pastebin.com/csWx5Sbb

+0

Benvenuti in Stackoverflow! Generalmente ci piacciono le risposte sul sito per essere in grado di stare in piedi da sole - I collegamenti sono grandiosi, ma se quel collegamento dovesse mai rompersi la risposta dovrebbe avere abbastanza informazioni per essere ancora utile. Ti preghiamo di considerare di modificare la tua risposta per includere maggiori dettagli. Vedi le [FAQ] (http://www.stackoverflow.com/faq) per maggiori informazioni. – slm

Problemi correlati