我有一个看起来像这样的XML文档:如何克隆PHP中没有数据的独特XML结构?
<root>
<node/>
<node>
<sub>more</sub>
</node>
<node>
<sub>another</sub>
</node>
<node>value</node>
</root>
这里是我的伪代码:
import xml.
create empty-xml.
foreach child of imported-xml-root-node,
recursively clone node structure without data.
if clone does not match one already in empty-xml,
then add clone to empty-xml.
我想要得到的结果,看起来像这样:
<root>
<node/>
<node>
<sub/>
</node>
</root>
注意我的piddly示例数据只有3个节点深。在生产中,会有未知数量的后代,因此可接受的答案需要处理变量节点深度。
失败途径
我已审查The DOMNode class具有cloneNode
法,我想用递归选项,但它会采取一些额外的工作来清除数据。但是,虽然该类包含一个hasChildNodes
函数,它返回一个布尔值,但是我找不到实际返回子集合的方法。
$doc = new DOMDocument();
$doc->loadXML($xml);
$root_node = $doc->documentElement;
if ($root_node->hasChildNodes()) {
// looking for something like this:
// foreach ($root_node->children() as $child)
// $doppel = $child->cloneNode(true);
}
其次,我已经试过我的手与The SimpleXMLElement class它确实有一个真棒children
方法。虽然它没有递归选项,但我建立了一个简单的函数来克服它。但是这个类缺少一个clone/copyNode方法,而且我的函数膨胀成了一些令人讨厌的补偿。现在我正在考虑结合使用这两个类,所以我可以访问SimpleXMLElement::children
和DOMDocument::cloneNode
,但我可以告诉这不是干净利落,当然这个问题可以更好地解决。
$sxe = new SimpleXMLElement($xml);
$indentation = 0;
function getNamesRecursive($xml, &$indentation)
{
$indentation++;
foreach($xml->children() as $child) {
for($i=0;$i<$indentation;$i++)
echo "\t";
echo $child->getName() . "\n";
getNamesRecursive($child,$indentation);
}
$indentation--;
}
getNamesRecursive($sxe,$indentation);
便携式根节点的选择:'$ doc-> documentElement' – rjdown
@rjdown哦真棒,谢谢!我编辑了我的问题来解决这个问题。很高兴知道! –
[DOMNode :: $ childNodes](http://php.net/manual/de/class.domnode.php#domnode.props.childnodes)是属性,而不是方法。 – ThW