我需要使用Simple XML加载一个XML源,复制一个已存在的节点及其所有子节点,然后在渲染XML之前自定义此新节点的属性。有什么建议吗?
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();
在使用SimpleXML时,我发现最好的方法是一种变通方法。它相当简单,但很有效:
// 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中似乎不存在的功能的解决方法,因此需要注意,如果您之前定义过任何对象引用,我预计这将破坏它们。
$newnode['attribute'] = $attValue;
中打错了字,应该是 $newNode['attribute'] = $attValue;
。 - synkro