沃梦达 / 编程问答 / php问题 / 正文

如何通过 DOM 对象重命名 SimpleXML 中的标签?

How do you rename a tag in SimpleXML through a DOM object?(如何通过 DOM 对象重命名 SimpleXML 中的标签?)

本文介绍了如何通过 DOM 对象重命名 SimpleXML 中的标签?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题看起来很简单,但我无法访问 SimpleXMLElement 的标记名称.

The problem seems straightforward, but I'm having trouble getting access to the tag name of a SimpleXMLElement.

假设我有以下 XML 结构:

Let's say I have the follow XML structure:

<xml>
     <oldName>Stuff</oldName>
</xml>

我希望它看起来像这样:

And I want it to look like this:

<xml>
     <newName>Stuff</newName>
</xml>

是否可以在不复制整个对象的情况下做到这一点?

我已经开始意识到我处理这个问题的方式的错误.看来我需要将我的 SimpleXMLElement 转换为 DOM 对象.这样做后,我发现以我想要的方式操作对象非常困难(显然,由于某种原因,在 DOM 中重命名标签并不容易).

I've started to realize the errors of the ways I am approaching this problem. It seems that I need to convert my SimpleXMLElement into a DOM object. Upon doing so I find it very hard to manipulate the object in the way I want (apparently renaming tags in a DOM isn't easy to do for a reason).

所以...我可以通过导入将我的 SimpleXMLElement 导入到 DOM 对象中,但我发现很难进行克隆.

So... I am able to import my SimpleXMLElement into a DOM object with the import, but I am finding it difficult to do the clone.

以下克隆 DOM 对象背后的想法是否正确,或者我是否仍然遥不可及:

Is the following the right thinking behind cloning a DOM object or am I still way off:

$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);

推荐答案

以下可能是不使用 XSLT 复制节点的子节点和属性的最简单方法:

Here's what's probably the simplest way to copy a node's children and attributes without using 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);
}

你可以这样使用:

$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());

它将用具有新名称的克隆替换旧节点.

It will replace the old node with a clone with a new name.

但是请注意,这是原始节点内容的副本.如果你有任何指向旧节点的变量,它们现在是无效的.

Attention though, this is a copy of the original node's content. If you had any variable pointing to the old nodes, they are now invalid.

这篇关于如何通过 DOM 对象重命名 SimpleXML 中的标签?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:如何通过 DOM 对象重命名 SimpleXML 中的标签?

基础教程推荐