• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Eigener XML Reader

Gilles

Blogger
Moin,
Ich bin grade dabei einen eigenen XML Reader zu schreiben. Dabei arbeite ich mit DOMDocument und DOMXPath.
Wenn ich nun einen query absetze mit DOMXPath kriege ich ja eine DOMNodeList zurück. Ich habe eine Funktion geschrieben, die mir für alle Nodes die Values ausliest. Jedoch funktioniert das nur richtig, wenn sich keine weiteren Elemente mehr innerhalb des angesteuerten Element befinden.
Nehmen wir an wir haben folgenden Aufbau
Code:
<?xml version="1.0" encoding="utf-8"?>
<characters>
 <character>
     <name>Gilles</name>
    <class>Archer</class>
 </character>
 <character>
  <name>Johnny</name>
  <class>Knight</class>
 </character>
</characters>

Wenn ich in meiner Klasse nun folgendes mache:
PHP:
var_dump($xml->getElementsValue("/characters/character"));

Sieht das Array folgender Maßen aus:
array(2) { [0]=> string(17) " Gilles Archer " [1]=> string(20) " Johnny Knight " }

gibt es denn eine Möglichkeit abufragen ob sich noch andere Elemente an der Stelle befinden, sodass ich eine Rekursion machen kann?
Hoffe ihr versteht was ich meine :D
Hab dann folgendes vor. Er soll mir in dem Fall ein Array zurück geben

[n]['name']
['class']
 
Gilles schrieb:
Ich habe eine Funktion geschrieben, die mir für alle Nodes die Values ausliest. Jedoch funktioniert das nur richtig, wenn sich keine weiteren Elemente mehr innerhalb des angesteuerten Element befinden.

Wäre vielleicht eine gute Idee gewesen, die Funktion zu posten. ;)

Meinst du sowas?

PHP:
<?php

class MyXmlParser
{
    protected $_domDocument = null;

    public function __construct($xmlCode)
    {
        $this->_domDocument = new DOMDocument();
        $this->_domDocument->loadXML($xmlCode);
    }

    protected function _flattenNode(DOMNode $node)
    {
        $ret = '';

        if ($node->hasChildNodes()) {
            if ($node->firstChild === $node->lastChild
                && $node->firstChild->nodeType == XML_TEXT_NODE
            ) {
                // Node contains nothing but a text node, return its value
                $ret = trim($node->nodeValue);
            } else {
                // Otherwise, do recursion
                $ret = array();
                foreach ($node->childNodes as $child) {
                    if ($child->nodeType != XML_TEXT_NODE) {
                        $ret[$child->nodeName] = $this->_flattenNode($child);
                    }
                }
            }
        }

        return $ret;
    }

    public function getElementsValue($xpathExpr)
    {
        $ret = array();
        
        $xpath = new DOMXPath($this->_domDocument);
        foreach ($xpath->query($xpathExpr, $this->_domDocument) as $node) {
            $ret[] = $this->_flattenNode($node);
        }

        return $ret;
    }
}

$xmlCode = <<<EOT
<?xml version="1.0" encoding="utf-8"?>
<characters>
 <character>
     <name>Gilles</name>
    <class>Archer</class>
    <stats>
      <strength>12</strength>
      <agility>15</agility>
    </stats>
 </character>
 <character>
  <name>Johnny</name>
  <class>Knight</class>
 </character>
</characters>
EOT;

$xml = new MyXmlParser($xmlCode);

print_r($xml->getElementsValue('/characters/character'));
 
Zurück
Oben