问题似乎很简单,但我无法访问SimpleXMLElement的标记名称.
假设我有以下XML结构:
<xml>
<oldName>Stuff</oldName>
</xml>
Run Code Online (Sandbox Code Playgroud)
我希望它看起来像这样:
<xml>
<newName>Stuff</newName>
</xml>
Run Code Online (Sandbox Code Playgroud)
这可能不做整个对象的副本吗?
我已经开始意识到我正在接近这个问题的方式的错误.似乎我需要将我的SimpleXMLElement转换为DOM对象.这样做后,我发现以我想要的方式操作对象非常困难(显然在DOM中重命名标签并不容易做到这一点).
所以...我能够通过导入将我的SimpleXMLElement导入到DOM对象中,但我发现很难进行克隆.
以下是克隆DOM对象背后的正确想法,还是我仍然离开:
$old = $dom->getElementsByTagName('old')->item(0); // The tag is unique in my case
$new = $dom->createElement('new');
/* ... some recursive logic to copy attributes and children of the $old node ... */
$old->ownerDocument->appendChild($new);
$new->ownerDocument->removeChild($old);
Run Code Online (Sandbox Code Playgroud)
这可能是在不使用XSLT的情况下复制节点的子节点和属性的最简单方法:
function clonishNode(DOMNode $oldNode, $newName, $newNS = null)
{
if (isset($newNS))
{
$newNode = $oldNode->ownerDocument->createElementNS($newNS, $newName);
}
else
{
$newNode = $oldNode->ownerDocument->createElement($newName);
}
foreach ($oldNode->attributes as $attr)
{
$newNode->appendChild($attr->cloneNode());
}
foreach ($oldNode->childNodes as $child)
{
$newNode->appendChild($child->cloneNode(true));
}
$oldNode->parentNode->replaceChild($newNode, $oldNode);
}
Run Code Online (Sandbox Code Playgroud)
你可以用这种方式:
$dom = new DOMDocument;
$dom->loadXML('<foo><bar x="1" y="2">x<baz/>y<quux/>z</bar></foo>');
$oldNode = $dom->getElementsByTagName('bar')->item(0);
clonishNode($oldNode, 'BXR');
// Same but with a new namespace
//clonishNode($oldNode, 'newns:BXR', 'http://newns');
die($dom->saveXML());
Run Code Online (Sandbox Code Playgroud)
它将使用具有新名称的克隆替换旧节点.
但请注意,这是原始节点内容的副本.如果您有任何指向旧节点的变量,它们现在无效.
| 归档时间: |
|
| 查看次数: |
4058 次 |
| 最近记录: |