Unable to remove all children from the XML document (PHP)

和自甴很熟 提交于 2020-01-05 05:58:07

问题


Unable to remove all children from the XML document

<?xml version="1.0" encoding="UTF-8"?>
    <routes>
      <route name="admin" />
      <!---->
      <route name="blog" bla bla/>
      <route name="blog" bla bla/>
      <route name="blog" bla bla/>
    </routes>


$xml = simplexml_load_file('routes.xml');

$dom_sxe = dom_import_simplexml($xml); $dom = new \DOMDocument('1.0'); $dom_sxe = $dom->importNode($dom_sxe, true); $dom_sxe = $dom->appendChild($dom_sxe); foreach ($dom->getElementsByTagName('route') as $route) { if($route->getAttribute('name') === 'blog') { $route->parentNode->removeChild($route); echo $route->getAttribute('name'); } } echo $dom->saveXML();

removes only 2 elements with the attribute blog


回答1:


The problem is that you are modifying the document while looping through it - a bit like modifying an array in the middle of a foreach loop.

Note that $dom->getElementsByTagName "returns a new instance of class DOMNodeList" not just an array. So as the loop goes round it is retrieving the elements as it goes; removing one will mess up its assumptions about what exists.

One solution to this is to copy the entire list of matches into a plain array before you loop over it. There is a built-in function iterator_to_array() which will do just that for you all in one go - basically, it runs a foreach over the iterable object, and collects the values into an array.

So the simplest (though not necessarily most readable etc) solution is to change this line:

foreach ($dom->getElementsByTagName('route') as $route)

to this:

foreach (iterator_to_array($dom->getElementsByTagName('route')) as $route)

Here's a live demo of the fixed code.



来源:https://stackoverflow.com/questions/18418991/unable-to-remove-all-children-from-the-xml-document-php

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!