Maar ik betwijfel het of het wel de netste methode is. Ook betwijfel ik of dat xml bestand wel valid is, aangezien de xml namespace nergens is gedeclareerd.
Dankzij heel wat hulp van m'n beste collega jmoe er eindelijk uitgeraakt.
SimpleXML is Simple, maar dus niet om ingewikkelde dingen te doen.
Voor en nadelen?
+ Eenvoudige syntax
+ Eenvoudige funcites
+ gebruik van $xml->node->subnode notatie
- geen (goede) ondersteuning voor attributen
- eens je data in een SimpleXML object steekt is het nog moeilijk aan te passen (binnen dat object)
Conclusie: gebruik DOMelement voor bewerkingen, en laad die dan in in SimpleXML voor gemakkelijk gebruik.
Stukje code?
Om te vermijden dat je steeds op voorhand je path moet kennen (alsook de juiste xpath expressie (vb. [@xml:lang='nl']) in een situatie waaring je een xml als volgt opbouwd:
De volgende code vereenvoudigd het selecteren van een node waarbij je een x-aantal nodes hebt voor verschillende talen alsook de mogelijkheid tot landspecifieke node.
De taal - locatie is op voorhand gekend en wordt meegegeven.
<?php
class StringBundle
{
const NAMESPACE_XML = 'http://www.w3.org/XML/1998/namespace';
protected $locale;
protected $language;
protected $xml;
/*construct the SimpleXML obj. without the unwanted nodes*/
public function __construct($identifier, $locale)
{
$this->language = strstr($this->locale, '-', true);
$xml = new \DOMDocument();
$elementFileName = $identifier.".xml";
$elementFilePath = "xml/".$elementFileName;
if(file_exists($elementFilePath))
{
$xml->load($elementFilePath);
$xml->saveXML();
$this->cleanThis($xml->documentElement);
}
$this->bundle = simplexml_import_dom($xml);
}
/**
* remove the unwanted lang
*/
protected function cleanThis(\DOMNode $node = null)
{
if ($node->hasChildNodes())
{
$localeNode = $langNode = null;
for ($i = $node->childNodes->length - 1; $i >= 0; $i--)
{
$child = $node->childNodes->item($i);
if (!$child instanceof \DOMElement)
{
continue;
}
if ($child->hasAttributeNS(self::NAMESPACE_XML, 'lang'))
{
$lang = $child->getAttributeNS(self::NAMESPACE_XML, 'lang');
if ($lang === $this->locale)
{
$localeNode = $child;
if ($langNode)
{
$langNode->parentNode->removeChild($langNode);
}
}
else if ($lang === $this->language && !$localeNode)
{
$langNode = $child;
}
else
{
$node->removeChild($child);
}
}
$this->removeUnwantedLocales($child);
}
}
}
/**
* Magic getter
* return SimpleXML
*/
public function __get($name)
{
return $this->bundle->$name;
}
}
?>
dus wanneer we nu een xml willen aanroepen in de juiste taal:
<?php
$getString = new StringBundle('test', 'nl');
echo $getString->thetitle;
?>