2010-08-05 23 views
10

Tengo dos árboles XML y me gustaría agregar un árbol como hoja al otro.SimpleXML: agregar un árbol a otro

parecer:

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

no funciona, ya que las copias sólo el primer nodo raíz.

Ok, entonces pensé que atravesaría todo el primer árbol, agregando cada elemento uno por uno al segundo árbol.

Pero considere XML como esto:

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

¿Cómo accedo a "CCC"? tree1->children() devuelve solo "bbb" ....

Respuesta

25

No puede agregar un "árbol" directamente utilizando SimpleXML, como ha visto. Sin embargo, puede usar algunos métodos DOM para hacer el trabajo pesado mientras trabaja en el mismo XML subyacente.

$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

¿El excatly lo que yo quiero, muchas gracias! –

+0

Cuando hago esto, los espacios de nombres en el nodo que estoy importando se descartan. ¿Cómo evito esto? –

0

muy agradable Theo Heikonnen ajustes Leve hacer que funcione de la manera que quería

 
    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

Esto es agradable solución de hacer comentarios sobre PHP manual page (utilizando sólo SimpleXML, no 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); 
    } 
} 

También hay ejemplos de uso.

+1

Esto fue muy útil. Para mis datos, necesitaba ajustar el segundo parámetro de addChild en htmlspecialchars() –

10

Puede utilizar esta clase para simplexml objetos que aceptan niños anexan

<?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); 
      } 
     } 
    } 
} 
Cuestiones relacionadas