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

时间:2010-11-14 12:03:29

标签: php xml recursion nodes

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

我尝试了这段代码,但它没有用......

$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 个答案:

答案 0 :(得分:4)

  

目标是删除整个节点而离开其他节点(实际上还有更多节点,但为了简单起见,此示例显示了所有节点

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

答案 1 :(得分:1)

当我使用接受的答案时,它不会删除所有出现的标签。 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();