每个parentNode都有PHP replaceChild

时间:2011-12-07 13:34:16

标签: php xml domdocument

我正在使用此PHP代码替换XML文件中的一系列节点:

<?php
$xml = "
<products>
<product>
<ItemId>531670</ItemId>
<modelNumber>METRA ELECTRONICS/MOBILE AUDIO</modelNumber>
<name>Buy</name>
<name>Car, Marine &amp; GPS</name>
<name>Car Installation Parts</name>
<name>Deck Installation Parts</name>
<name>Antennas &amp; Adapters</name>
</product>
<product>
<ItemId>531670</ItemId>
<modelNumber>METRA ELECTRONICS/MOBILE AUDIO</modelNumber>
<name>Buy</name>
<name>Car, Marine &amp; GPS</name>
<name>Car Installation Parts</name>
<name>Deck Installation Parts</name>
<name>Antennas &amp; Adapters</name>
 </product>
<product>
<ItemId>531670</ItemId>
<modelNumber>METRA ELECTRONICS/MOBILE AUDIO</modelNumber>
<name>Buy</name>
<name>Car, Marine &amp; GPS</name>
<name>Car Installation Parts</name>
<name>Deck Installation Parts</name>
<name>Antennas &amp; Adapters</name>
</product>
<product>
<ItemId>531670</ItemId>
<modelNumber>METRA ELECTRONICS/MOBILE AUDIO</modelNumber>
<name>Buy</name>
<name>Car, Marine &amp; GPS</name>
<name>Car Installation Parts</name>
<name>Deck Installation Parts</name>
<name>Antennas &amp; Adapters</name>
</product>
<product>
<ItemId>531670</ItemId>
<modelNumber>METRA ELECTRONICS/MOBILE AUDIO</modelNumber>
<name>Buy</name>
<name>Car, Marine &amp; GPS</name>
<name>Car Installation Parts</name>
<name>Deck Installation Parts</name>
<name>Antennas &amp; 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($xml, 'name', 'Source');
$xml = renameTags($xml, 'name', 'parentCategory');
$xml = renameTags($xml, 'name', 'Category');
$xml = renameTags($xml, 'name', 'subCategory');
$xml = renameTags($xml, 'name', 'sisterCategory');

echo $xml;
?>

但是,此代码仅替换并且仅适用于一个产品集。 我想我需要在函数中的某个地方调用foreach语句,该函数由foreach parentNode('product')替换标记名称。我需要为函数添加什么来迭代所有产品集?

上面的代码将打印出这个:(注意第一组名称节点已经消失,并被指定的新节点替换)

<?xml version="1.0"?>
<products>
<product>
<ItemId>531670</ItemId>
<modelNumber>METRA ELECTRONICS/MOBILE AUDIO</modelNumber>
<Source>Buy</Source>
<parentCategory>Car, Marine &amp; GPS</parentCategory>
<Category>Car Installation Parts</Category>
<subCategory>Deck Installation Parts</subCategory>
<sisterCategory>Antennas &amp; Adapters</sisterCategory></product>
<product>
<ItemId>531670</ItemId>
<modelNumber>METRA ELECTRONICS/MOBILE AUDIO</modelNumber>
<name>Buy</name>
<name>Car, Marine &amp; GPS</name>
<name>Car Installation Parts</name>
<name>Deck Installation Parts</name>
<name>Antennas &amp; Adapters</name>
</product>
<product>
<ItemId>531670</ItemId>
<modelNumber>METRA ELECTRONICS/MOBILE AUDIO</modelNumber>
<name>Buy</name>
<name>Car, Marine &amp; GPS</name>
<name>Car Installation Parts</name>
<name>Deck Installation Parts</name>
<name>Antennas &amp; Adapters</name>
</product>
<product>
<ItemId>531670</ItemId>
<modelNumber>METRA ELECTRONICS/MOBILE AUDIO</modelNumber>
<name>Buy</name>
<name>Car, Marine &amp; GPS</name>
<name>Car Installation Parts</name>
<name>Deck Installation Parts</name>
<name>Antennas &amp; Adapters</name>
</product>
<product>
<ItemId>531670</ItemId>
<modelNumber>METRA ELECTRONICS/MOBILE AUDIO</modelNumber>
<name>Buy</name>
<name>Car, Marine &amp; GPS</name>
<name>Car Installation Parts</name>
<name>Deck Installation Parts</name>
<name>Antennas &amp; Adapters</name>
</product>
</products>

如您所见,它只替换了一个产品实例。

1 个答案:

答案 0 :(得分:4)

该foreach的中断是你的问题:它在它遇到的第一个<name>节点处停止,无论它在文档中的什么位置。

首先,您必须遍历产品,然后通过产品的<name>节点。如下所示:

function renameTags($xml, $old, $new) {
    $toRemove = array();
    $dom = new DOMDocument();
    $dom->loadXML($xml);
    $products = $dom->getElementsByTagName('product');

    foreach($products as $product) {
        $nodes = $product->getElementsByTagName($old);

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