2

我有一个简单的任务:<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只是查询列表的持有者。这个名字没有任何意义。

4

2 回答 2

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>
于 2010-11-14T12:13:25.110 回答
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();
于 2019-03-19T21:17:51.497 回答