问题似乎很简单,但是我在访问SimpleXMLElement的标记名称时遇到了麻烦。
假设我有以下XML结构:
<xml>
<oldName>Stuff</oldName>
</xml>
我想让它看起来像这样:
<xml>
<newName>Stuff</newName>
</xml>
不复制整个对象是否可行?罢工>
所以…我能够通过导入将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);
下面可能是不使用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());
它将用一个具有新名称的克隆替换旧节点。
但请注意,这是原始节点内容的复制。如果您有任何指向旧节点的变量,它们现在是无效的。也许更简单的方法是使用preg函数替换XML源字符串的标记?
<清洁方式/strong>
创建XSLT XML转换文件,并使用xsl PHP扩展对其进行翻译。
请参阅这个答案—使用XSLT重命名节点。PHP代码部分可在PHP文档中找到
不复制整个对象是否可行?
不,它不是。
您可以通过"单位变换"在XSLT中完成。如果您搜索"重命名标记"one_answers"标识转换",您应该会找到一些示例,假设XSLT是一个选项。
虽然晚了,但我还是通过替换掉xml中的所有内容提出了以下解决方案。我想这可能会帮助一些人,因为我在网上找不到任何好的解决方案,而不复制所有的孩子。
function RenameNode(SimpleXMLElement $Entire_XML, SimpleXMLElement $Node, $New_Title)
{
$Full_XML = $Entire_XML->asXML();
$Old_Title = $Node->getName();
$XML_String = $Node->asXML();
$Replaced = preg_replace("/$Old_Title/", $New_Title, $XML_String, 1);
if (count($Node->children())>0)
{
$Replaced = strrev(
preg_replace(
strrev("/$Old_Title/"),
strrev($New_Title),
strrev($Replaced),
1
)
);
}
$Full_XML = str_replace($XML_String, $Replaced, $Full_XML);
return simplexml_load_string($Full_XML);
}
旁注:这个函数可以简化,但为了在这里发布,我很快重写了这个函数。我使用的原始函数看起来有点不同