2010-03-01 49 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