代码之家  ›  专栏  ›  技术社区  ›  HX_unbanned

使用PHP从XML文档中删除特定类型的所有元素

  •  2
  • HX_unbanned  · 技术社区  · 14 年前

    我有一个简单的任务:删除 <places> 从XML文档中提取的节点及其后代,保留其他节点。

    我试过这个代码,但没用…

    $document->preserveWhiteSpace = false; 
    $books = $xpath->query('piletilve_info/places');
    //echo "4";
    
    foreach ($books as $places) {
        while($places->hasChildNodes()) {
            $places->removeChild($places->childNodes->item(0));
        }
    
        $places->parentNode->removeChild($places);
    }
    

    要处理的源XML:

    <piletilve_info>
       <places>
          <place>
            ...
          </place>
       </places>
       <other node>
          ...
       </other node>
    </piletilve_info>
    

    在实际数据中,有更多的节点不是位置,但为了简单起见,这个示例只显示了一些节点。

    我看到了C示例,但我没有设法将代码移植到PHP。

    澄清 :在代码段中,变量 $books 只是查询列表的持有者。这个名字没有意义。

    2 回复  |  直到 5 年前
        1
  •  4
  •   Gordon Haim Evgi    14 年前

    目标是删除整个节点,留下其他节点(实际上还有更多的节点,但为了简单起见,这个示例显示了

    $dom = new DOMDocument;
    $dom->load('places.xml');
    foreach ($dom->getElementsByTagName('places') as $places)
    {
        $places->parentNode->removeChild($places);
    }
    echo $dom->saveXml();
    

    将全部删除 <places> 文档中任何位置的元素,包括任何子元素。

    输出:

    <?xml version="1.0"?>
    <piletilve_info>
    
       <other>
          ...
       </other>
    </piletilve_info>
    
        2
  •  0
  •   Tomas    5 年前

    当我使用接受的答案时,它不会删除所有出现的标签。 foreach循环将跳过标记,可能是因为foreach依赖于内部数组指针,在循环中更改它会导致意外的行为。

    我发现一个有效的解决方案是这样的。

    $dom = new DOMDocument;
    $dom->load('places.xml');
    $placesNodes = $dom->getElementsByTagName('places') 
    while ($placesNodes->length > 0) {
        $node = $placesNodes->item(0);
        $node->parentNode->removeChild($node);
    }
    echo $dom->saveXml();