2010-07-29 74 views
7

說我有XML:PHP的SimpleXML:在某些位置插入節點

<root> 
    <nodeA /> 
    <nodeA /> 
    <nodeA /> 
    <nodeC /> 
    <nodeC /> 
    <nodeC /> 
</root> 

如何插入 「節點B」 作爲和Cs之間?在PHP中,最好通過SimpleXML?像:

<root> 
    <nodeA /> 
    <nodeA /> 
    <nodeA /> 
    <nodeB /> 
    <nodeC /> 
    <nodeC /> 
    <nodeC /> 
</root> 
+1

我不確定你可以。從文檔看來,SimpleXML似乎是用於**真正**簡單的操作。 – MvanGeest 2010-07-29 09:36:57

+0

我不能以某種方式在其他地方存儲Cs,刪除它們,添加B,並從該臨時位置添加Cs?我只是不太熟悉PHP .... – 2010-07-29 09:43:03

回答

13

以下是在其他一些SimpleXMLElement之後插入新的SimpleXMLElement的函數。由於SimpleXML不可能直接使用它,因此它使用一些DOM類/方法來幕後工作。

function simplexml_insert_after(SimpleXMLElement $insert, SimpleXMLElement $target) 
{ 
    $target_dom = dom_import_simplexml($target); 
    $insert_dom = $target_dom->ownerDocument->importNode(dom_import_simplexml($insert), true); 
    if ($target_dom->nextSibling) { 
     return $target_dom->parentNode->insertBefore($insert_dom, $target_dom->nextSibling); 
    } else { 
     return $target_dom->parentNode->appendChild($insert_dom); 
    } 
} 

以及它如何可以使用(具體到你的問題)的例子:

$sxe = new SimpleXMLElement('<root><nodeA/><nodeA/><nodeA/><nodeC/><nodeC/><nodeC/></root>'); 
// New element to be inserted 
$insert = new SimpleXMLElement("<nodeB/>"); 
// Get the last nodeA element 
$target = current($sxe->xpath('//nodeA[last()]')); 
// Insert the new element after the last nodeA 
simplexml_insert_after($insert, $target); 
// Peek at the new XML 
echo $sxe->asXML(); 

如果你想/需要的如何這個作品的解釋(代碼是相當簡單的,但可能包括外國概念),請問。

+0

是我還是在simplexml_insert_after中使用$ sxe參數? – GolezTrol 2011-06-01 10:54:43

+1

這不是你,爲什麼在回答問題時沒有樂趣? :) – salathe 2011-06-01 11:01:00

+0

是的,爲什麼不。 :)感謝您的回答,b.t.w.我把libery用來構建我自己的。 :) – GolezTrol 2011-06-01 12:10:39

4

Salathe的答案都幫助我,但因爲我用的SimpleXMLElement的AddChild方法,我在尋找解決辦法,使插入孩子的第一個孩子更加透明。解決的辦法是採取基於DOM的功能,並把它藏在的SimpleXMLElement的一個子類:

class SimpleXMLElementEx extends SimpleXMLElement 
{ 
    public function insertChildFirst($name, $value, $namespace) 
    { 
     // Convert ourselves to DOM. 
     $targetDom = dom_import_simplexml($this); 
     // Check for children 
     $hasChildren = $targetDom->hasChildNodes(); 

     // Create the new childnode. 
     $newNode = $this->addChild($name, $value, $namespace); 

     // Put in the first position. 
     if ($hasChildren) 
     { 
      $newNodeDom = $targetDom->ownerDocument->importNode(dom_import_simplexml($newNode), true); 
      $targetDom->insertBefore($newNodeDom, $targetDom->firstChild); 
     } 

     // Return the new node. 
     return $newNode; 
    } 
} 

畢竟,SimpleXML的允許指定要使用的元素類:

$xml = simplexml_load_file($inputFile, 'SimpleXMLElementEx'); 

現在,您可以撥打insertChildFirst在任何元素上插入新的孩子作爲第一個孩子。該方法將新元素作爲SimpleXML元素返回,因此它的使用與addChild類似。當然,創建一個insertChild方法很容易,可以指定一個確切的元素來插入項目,但由於我現在不需要,所以我決定不這樣做。