我有一个XML文件,目前有4个具有相同名称的节点: 该文件如下所示:(data.xml)
<?xml version="1.0"?>
<products>
<product>
<ItemId>531670</ItemId>
<modelNumber>METRA ELECTRONICS/MOBILE AUDIO</modelNumber>
<name>Buy</name>
<name>Car, Marine & GPS</name>
<name>Car Installation Parts</name>
<name>Deck Installation Parts</name>
<name>Antennas & Adapters</name>
</product>
</products>
有4个节点具有相同的名称。 (名称节点)。
然后,我使用此PHP代码替换节点名称
<?php
/**
* @param $xml string Your XML
* @param $old string Name of the old tag
* @param $new string Name of the new tag
* @return string New XML
*/
function renameTags($xml, $old, $new)
{
$dom = new DOMDocument();
$dom->loadXML($xml);
$nodes = $dom->getElementsByTagName($old);
$toRemove = array();
foreach ($nodes as $node)
{
$newNode = $dom->createElement($new);
foreach ($node->attributes as $attribute)
{
$newNode->setAttribute($attribute->name, $attribute->value);
}
foreach ($node->childNodes as $child)
{
$newNode->appendChild($node->removeChild($child));
}
$node->parentNode->appendChild($newNode);
$toRemove[] = $node;
}
foreach ($toRemove as $node)
{
$node->parentNode->removeChild($node);
}
return $dom->saveXML();
}
// Load XML from file data.xml
$xml = file_get_contents('data.xml');
$xml = renameTags($xml, 'name', 'newName');
echo $xml;
?>
此函数用newName替换所有名称节点;但是,我只想替换名称标签的一个实例,因为我想重命名每个名称标签。 如果我打电话给另一个 $ xml = renameTags($ xml,'name','newName2');
它不会工作,它只会使用$ xml的第一个实例。
任何想法如何更改我的代码以允许我单独替换每个名称节点?
答案 0 :(得分:2)
如果您只想重命名遇到的第一个节点,请在第一个break;
循环的末尾添加foreach
语句,如第一个示例所示。然而,这是非常低效的,并且在底部的第二个(正确)示例中演示了更好的方法。
错误的方式 每当你像这样替换XML时,天使就会流下眼泪......
$src = "
<products>
<product>
<ItemId>531670</ItemId>
<modelNumber>METRA ELECTRONICS/MOBILE AUDIO</modelNumber>
<name>Buy</name>
<name>Car, Marine & GPS</name>
<name>Car Installation Parts</name>
<name>Deck Installation Parts</name>
<name>Antennas & Adapters</name>
</product>
</products>
";
function renameTags($xml, $old, $new)
{
$dom = new DOMDocument();
$dom->loadXML($xml);
$nodes = $dom->getElementsByTagName($old);
$toRemove = array();
foreach ($nodes as $node)
{
$newNode = $dom->createElement($new);
foreach ($node->attributes as $attribute)
{
$newNode->setAttribute($attribute->name, $attribute->value);
}
foreach ($node->childNodes as $child)
{
$newNode->appendChild($node->removeChild($child));
}
$node->parentNode->appendChild($newNode);
$toRemove[] = $node;
break;
}
foreach ($toRemove as $node)
{
$node->parentNode->removeChild($node);
}
$dom->formatOutput = TRUE;
return $dom->saveXML();
}
$xml = renameTags($src, 'name', 'newName');
echo $xml;
正确的方式
function renameTags($xml, $old, $new)
{
$dom = new DOMDocument();
$dom->loadXML($xml);
// find the first node with the specified tag name
$oldNode = $dom->getElementsByTagName($old)->item(0);
// clone the node (deep copy)
$doppelganger = $oldNode->cloneNode(TRUE);
// import our cloned node to this dom document
$doppelganger = $dom->importNode($doppelganger, true);
// Create new node with the value from the copied node
$newNode = $dom->createElement($new, $doppelganger->nodeValue);
// update all the attributes of the new node with those from the copy
foreach ($doppelganger->attributes as $attrName => $attrNode) {
$newNode->setAttribute($attrName, $attrNode);
}
// append the newNode copy to the dom
$oldNode->parentNode->appendChild($newNode);
// remove the old node
$oldNode->parentNode->removeChild($oldNode);
$dom->formatOutput = TRUE;
return $dom->saveXML();
}