0

so im making this website that has to have multiple languages working on it. I've poked around and came to the conclusion that i should use XML-files, one for each language. Witch makes sense to me, but here's my problem:

I've made a XML-file looking like this:

<?xml version="1.0" encoding="utf-8"?>
<translations>
  <frontpage>
    <!--Main translation-->
    <translation string="email" value="E-mail" />
    <translation string="password" value="Password" />
    <translation string="createacc" value="Create account" />
    <translation string="login" value="Login" />
    <!--Errors-->
    <translation string="erroremail1" value="E-mail not valid" />
    <translation string="erroremail2" value="There's no account with that e-mail" />
    <translation string="errorpass" value="Incorrect password" />
  </frontpage>
</translations>

But i just dont get how XMLReader and DOMDocument, from the PHP libraries, works. This is the code i have so far:

public function Translate($page,$string,$variables = array()) {
    $reader = new XMLReader();
    $reader->open(www::findFile("lang/".$this->short.".xml"));
    //Here i want to find the <translation> with the attribute string that is === $string
    //With the parent of $page (fx. Translate("frontpage","erroremail1"))
    $reader->close();

    $find = array();
    for ($x = 0; count($find) != count($variables); $x++) $find[] = "{".$x."}";
    return (isset($value)) ? str_replace($find,$variables,$value) : "NOT TRANSLATED (".$string.")";
}

SOLUTION:

public function Translate($page,$string,$variables = array()) {
    //Read from XML 
    $reader = simplexml_load_file(www::findFile("lang/".$this->short.".xml"));
    foreach ($reader->$page->translation as $t) if ($t['string'] == $string) { $value = $t['value']; break; }
    $find = array();
    for ($x = 0; count($find) != count($variables); $x++) $find[] = "{".$x."}";
    return (isset($value)) ? str_replace($find,$variables,$value) : "NOT TRANSLATED (".$string.")";
}
CoBolt
  • 442
  • 2
  • 11
  • simplexml_load_file is the better choice. http://blog.teamtreehouse.com/how-to-parse-xml-with-php5 – Sibiraj PR Mar 06 '13 at 08:46
  • If you don't know enough to get XMLReader or DOMDocument or SimpleXML working, then are you really sure that deciding on using XML was such a good idea – Mark Baker Mar 06 '13 at 09:01
  • Mark Baker, yes i am. I would rather use a few days learning this stuff then use some kind of backdoor. Sibiraj thx for the link, it really help'd – CoBolt Mar 06 '13 at 09:22

1 Answers1

0

If you encode the language as well inside the file you can - but must not - put multiple languages inside the same file. XML does support both. Just saying, because you've chosen XML and that would be one benefit.

For inside your program you only need a mapping as of

page + string + language:= translation

As in your operation this is one language only you can ignore it even, therefore you can just take an array:

$translations[$string]

per each language and page. All you need to do then is to convert your file into an array:

$getTranslations = function($file, $page) {
   $translations = [];
   foreach(simplexml_load_file($file)->$page->translation as $translation)
   {
       $translations[$translation['string']] = $translation['value'];
   }
   return $translations;        
}

$translations = $getTranslations($file, $page); 

if (isset($translations[$string]) {
   // found
} else {
   // not found (e.g. fallback to $string)
}

This sure leaves a lot of room for optimizations, e.g. you could keep the translation per file / page in memory so you only need to load it once. Or you could use xpath() instead to obtain the value.

hakre
  • 193,403
  • 52
  • 435
  • 836