SimpleXML: добавить одно дерево к другому

У меня есть два дерева XML и хотелось бы добавить одно дерево в виде листа к другому.

По всей видимости:

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

не работает, поскольку он копирует только первый корневой узел.

Итак, тогда я думал, что пройду все первое дерево, добавив каждый элемент один за другим ко второму.

Но рассмотрите XML следующим образом:

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

Как получить доступ к «ccc»? tree1->children() возвращает только «bbb» ….

Вы не можете добавить «дерево» напрямую, используя SimpleXML, как вы видели. Тем не менее, вы можете использовать некоторые методы DOM для тяжелого подъема для вас, все еще работая над одним и тем же базовым XML.

 $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; 

Вы можете использовать этот класс для объектов SimpleXML, которые принимают дочерние приложения

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

Это хорошее решение из комментария на странице руководства PHP (используя только SimpleXML, а не 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); } } 

Там также пример использования.

Очень хороший Тео Хейконнн Небольшая настройка, чтобы заставить работать так, как я хотел

     функция addubtree (& $ xml1, & $ xml2)
     {// Создаем новые DOMElements из двух SimpleXMLElements
         $ dom1 = dom_import_simplexml ($ xml1);
         $ dom2 = dom_import_simplexml ($ xml2);
         // Импортируем в документ
         $ dom2 = $ dom1-> ownerDocument-> importNode ($ dom2, TRUE);
         // Добавить в 
         $ Dom1-> AppendChild ($ dom2);
     }

     $ xml1 = новый SimpleXMLElement ('<xml />');
     $ xml2 = новый SimpleXMLElement ('<sub />');

     $ Xml2-> AddChild ( 'тест', 'данные');
     $ Темп = $ xml1-> AddChild ( 'sub1');

     header ('Content-type: text / xml');
     header («Pragma: public»);
     header ('Cache-control: private');
     header ('Истекает: -1');
     addsubtree ($ темп, $ xml2);

     // Мы все еще можем использовать SimpleXML!  (мяу)
     echo $ xml1-> asXML ();