【发布时间】:2010-03-01 13:42:27
【问题描述】:
我需要使用简单 XML 加载 XML 源,复制现有节点及其所有子节点,然后在呈现 XML 之前自定义此新节点的属性。有什么建议吗?
【问题讨论】:
我需要使用简单 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 中似乎不存在的功能的一种解决方法,因此您需要注意,我预计这会破坏您迄今为止定义的任何对象引用(如果有的话)。
【讨论】: