代码之家  ›  专栏  ›  技术社区  ›  Laguna Seca

无法从XML文档(PHP)中删除所有子项

  •  1
  • Laguna Seca  · 技术社区  · 11 年前

    无法从XML文档中删除所有子项

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

    仅删除具有该属性的2个元素 博客

    1 回复  |  直到 11 年前
        1
  •  1
  •   IMSoP    11 年前

    问题是您在修改文档的同时对其进行循环,这有点像在 foreach

    请注意 $dom->getElementsByTagName "returns a new instance of class DOMNodeList " 不仅仅是一个数组。因此,随着循环的进行,它正在检索元素;删除一个会打乱它对现存事物的假设。

    一个解决方案是在循环之前将整个匹配列表复制到一个普通数组中 iterator_to_array() 这将一次为你们所有人做到这一点——基本上,它运行 前臂 在可迭代对象上,并将值收集到一个数组中。

    因此,最简单的(尽管不一定是最可读的等)解决方案是更改这一行:

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

    对此:

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

    Here's a live demo of the fixed code.