2010-08-05 11 views
10

Ich habe zwei XML-Bäume und möchte einen Baum als ein Blatt zum anderen hinzufügen.SimpleXML: einen Baum an einen anderen anhängen

Anscheinend:

$tree2->addChild('leaf', $tree1); 

nicht funktioniert, da es nur Kopien der ersten Wurzelknoten.

Ok, also dachte ich, ich würde den ganzen ersten Baum durchqueren und jedes Element einzeln zum zweiten hinzufügen.

Aber betrachten XML wie folgt aus:

<root> 
    aaa 
    <bbb/> 
    ccc 
</root> 

Wie greife ich auf "ccc"? tree1->children() gibt nur "bbb" zurück ....

Antwort

25

Sie können einen "Baum" nicht direkt mit SimpleXML hinzufügen, wie Sie gesehen haben. Sie können jedoch einige DOM-Methoden verwenden, um das Heavy-Lifting für Sie auszuführen, während Sie immer noch an demselben zugrunde liegenden XML-Code arbeiten.

$xmldict = new SimpleXMLElement('<dictionary><a/><b/><c/></dictionary>'); 
$kitty = new SimpleXMLElement('<cat><sound>meow</sound><texture>fuzzy</texture></cat>'); 

// Create new DOMElements from the two SimpleXMLElements 
$domdict = dom_import_simplexml($xmldict->c); 
$domcat = dom_import_simplexml($kitty); 

// Import the <cat> into the dictionary document 
$domcat = $domdict->ownerDocument->importNode($domcat, TRUE); 

// Append the <cat> to <c> in the dictionary 
$domdict->appendChild($domcat); 

// We can still use SimpleXML! (meow) 
echo $xmldict->c->cat->sound; 
+0

excatly anhängen nimmt, was ich will, vielen Dank! –

+0

Wenn ich dies tue, werden die Namespaces auf dem Knoten, den ich importiere, rausgeworfen. Wie verhindere ich das? –

0

Sehr schön Theo Heikonnen leichte Zwicken es die Art und Weise funktioniert Ich wollte

 
    function addsubtree(&$xml1,&$xml2) 
    {// Create new DOMElements from the two SimpleXMLElements 
     $dom1 = dom_import_simplexml($xml1); 
     $dom2 = dom_import_simplexml($xml2); 
     // Import the into the document 
     $dom2 = $dom1->ownerDocument->importNode($dom2, TRUE); 
     // Append the to 
     $dom1->appendChild($dom2); 
    } 

    $xml1 = new SimpleXMLElement('<xml/>'); 
    $xml2 = new SimpleXMLElement('<sub/>'); 

    $xml2->addChild('test','data'); 
    $temp=$xml1->addChild('sub1'); 

    header('Content-type: text/xml'); 
    header('Pragma: public'); 
    header('Cache-control: private'); 
    header('Expires: -1'); 
    addsubtree($temp,$xml2); 

    // We can still use SimpleXML! (meow) 
    echo $xml1->asXML(); 
8

Das ist schön Lösung von Kommentar auf PHP manual page (mit nur SimpleXML, nicht DOM):

function append_simplexml(&$simplexml_to, &$simplexml_from) 
{ 
    foreach ($simplexml_from->children() as $simplexml_child) 
    { 
     $simplexml_temp = $simplexml_to->addChild($simplexml_child->getName(), (string) $simplexml_child); 
     foreach ($simplexml_child->attributes() as $attr_key => $attr_value) 
     { 
      $simplexml_temp->addAttribute($attr_key, $attr_value); 
     } 

     append_simplexml($simplexml_temp, $simplexml_child); 
    } 
} 

Es gibt auch ein Beispiel für die Verwendung.

+1

Das war einfach hilfreich. Für meine Daten musste ich den zweiten Parameter von addChild in htmlspecialchars() einfügen –

10

können Sie diese Klasse verwenden, um Objekte simplexml die Kinder

<?php 

class MySimpleXMLElement extends SimpleXMLElement 
{ 
    /** 
    * Add SimpleXMLElement code into a SimpleXMLElement 
    * 
    * @param MySimpleXMLElement $append 
    */ 
    public function appendXML($append) 
    { 
     if ($append) { 
      if (strlen(trim((string)$append)) == 0) { 
       $xml = $this->addChild($append->getName()); 
      } else { 
       $xml = $this->addChild($append->getName(), (string)$append); 
      } 

      foreach ($append->children() as $child) { 
       $xml->appendXML($child); 
      } 

      foreach ($append->attributes() as $n => $v) { 
       $xml->addAttribute($n, $v); 
      } 
     } 
    } 
}