2010-08-05 179 views
10

我有兩個XML樹,並希望將一棵樹添加爲另一棵樹。SimpleXML:將一棵樹追加到另一棵樹

顯然:

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

不起作用,因爲它僅複製第一根節點。

好吧,那麼我想我會遍歷整個第一棵樹,將每個元素逐一添加到第二棵樹。

但考慮這樣的XML:

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

如何訪問 「CCC」? tree1->children()只返回「bbb」...。

回答

25

如您所見,您無法直接使用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; 
+0

是否excatly我想要的對象,非常感謝! – 2010-08-05 19:45:18

+0

當我這樣做時,我導入的節點上的名稱空間被拋出。我如何防止這種情況? – 2013-10-03 18:43:40

0

非常漂亮西奧Heikonnen 輕微的調整,以使其工作,我想要的方式

 
    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

這是評論很好的解決方案上PHP manual page(只使用了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); 
    } 
} 

還有一些使用示例。

+1

這很簡單有用。對於我的數據,我需要在htmlspecialchars()中包裝addChild的第二個參數 – 2016-10-26 16:29:22

10

你可以使用這個類的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); 
      } 
     } 
    } 
}