2010-03-01 69 views

回答

18

SimpleXML無法做到這一點,所以你必須使用DOM。好消息是DOM和SimpleXML是同一枚硬幣libxml的兩面。所以不管你使用的是SimpleXML還是DOM,你都在使用同一棵樹。這裏有一個例子:

$thing = simplexml_load_string(
    '<thing> 
     <node n="1"><child/></node> 
    </thing>' 
); 

$dom_thing = dom_import_simplexml($thing); 
$dom_node = dom_import_simplexml($thing->node); 
$dom_new = $dom_thing->appendChild($dom_node->cloneNode(true)); 

$new_node = simplexml_import_dom($dom_new); 
$new_node['n'] = 2; 

echo $thing->asXML(); 

如果你正在做那種事很多,你可以嘗試SimpleDOM,這是一個擴展的SimpleXML,可以讓你直接使用DOM的方法,沒有從和轉換DOM對象。

include 'SimpleDOM.php'; 
$thing = simpledom_load_string(
    '<thing> 
     <node n="1"><child/></node> 
    </thing>' 
); 

$new = $thing->appendChild($thing->node->cloneNode(true)); 
$new['n'] = 2; 

echo $thing->asXML(); 
+2

+1用於推薦DOM。我用simpleXML遇到了很多問題。不要使用SimpleXML,DOM功能更強大,並且不會更難使用。 – Keyo

+0

我必須注意到它也是因爲這非常重要。我並不抱歉花了半個小時用DOM重寫我的腳本。現在它更直接,更容易維護。 – ivkremer

3

使用SimpleXML,我找到的最佳方法是解決方法。這是非常BOBO,但它的工作原理:

// Strip it out so it's not passed by reference 
$newNode = new SimpleXMLElement($xml->someNode->asXML()); 

// Modify your value 
$newnode['attribute'] = $attValue; 

// Create a dummy placeholder for it wherever you need it 
$xml->addChild('replaceMe'); 

// Do a string replace on the empty fake node 
$xml = str_replace('<replaceMe/>',$newNode->asXML(),$xml->asXML()); 

// Convert back to the object 
$xml = new SimpleXMLElement($xml); # leave this out if you want the xml 

由於它是一種功能,似乎並不在那裏SimpleXML中的一種解決方法,你需要知道,我希望這將打破任何對象引用你我們已經定義了這一點,如果有的話。

+0

喜歡這個答案,很簡單,效果很棒。我不得不稍微調整一下這個答案,因爲'$ newNode-> asXML()'寫出了XML頭部,而不是原始的XML片段: $ domNode = dom_import_simplexml($ newNode); $ xml = str_replace('',$ domNode-> ownerDocument-> saveXML($ domNode),$ xml-> asXML()); – AaronP