PHP replaceChild for each parentNode

I am using this PHP code to replace a series of nodes in an XML file:

<?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; ?> 

However, this code is replaced and works only for one set of products. I think I need to call the foreach statement somewhere in the function consisting of foreach parentNode ('product') replacing the tag names. What do I need to add for a function to iterate over all product sets?

The above code will print this: (note that the first set of name nodes has disappeared and is replaced by the specified new nodes)

 <?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> 

As you can see, it replaces only one instance of the product.

+4
source share
1 answer

The gap in this foreach was your problem: it stopped at the first <name> node it collided with, no matter where it was in the document.

First you will need to skip the products, and then through the product nodes <name> . Something like the following:

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

Source: https://habr.com/ru/post/1385119/


All Articles