使用 XmlReader 读取文件时从 XML 文件中删除节点?

Delete node from XML file while reading it with XmlReader?

我有一个脚本使用 XMLReader 逐个节点读取 XML:

$z = new XMLReader;
$z->open('xmlfile.xml');
$doc = new DOMDocument;

while ($z->read() && $z->name !== 'item');
while ($z->name === 'item')
{
    $node = simplexml_import_dom($doc->importNode($z->expand(), true));

    //I read the node here 
    print_r($node);

    //Here I want to delete it
    //////////////////////////

    //move to next node
    $z->next('item');
}

我想在读取 XML 文件后删除节点 以避免再次调用脚本时多次读取相同的数据。最好的方法是什么?我可以在阅读文件时做到这一点吗?

我在其他地方找不到答案。

您无法边阅读文档边编辑.. 至少在没有大量杂乱低效代码的情况下不能。

最佳方法是:

1) 将整个文档读入第二个 DOMDocument 对象。

2) 当您从 XMLReader 输入流中一个接一个地读取节点时,在 DOMDocument 中找到相应的节点并在完成后将其删除。小心不要删除具有您尚未审核的子项的节点。

3) 完成后将新 DomDocument 保存为新文件名,并将其用作下一次编辑会话的输入源。

完成后,您将成为 DomDocument 操作方面的专家。

Post如果你运行遇到问题,一个新问题。

XML读者有个伙伴叫XML作家。因此,对于大型 XML 文件,您使用 XMLReader 读取 XML 文件,同时使用 XMLWriter 将 filtered/modified 数据写入新文件。

将文件的一部分扩展为DOM可以更轻松地阅读和修改这部分内容,但是您需要使用XMLWriter将XML结构序列化到新文件中.

我在 FluentDOM 中实现了功能(包括 collapse() 方法)。这是一个用法示例:

$xml = <<<'XML'
<persons>
  <person><name>Alice</name></person>
  <person><name>Bob</name></person>
  <person><name>Charlie</name></person>
</persons>
XML;

// Create the target writer and add the root element
$writer = new \FluentDOM\XMLWriter();
$writer->openUri('php://stdout');
$writer->setIndent(2);
$writer->startDocument();
$writer->startElement('persons');

// load the source into a reader
$reader = new \FluentDOM\XMLReader();
$reader->open('data://text/plain;base64,'.base64_encode($xml));

// iterate the person elements - the iterator expands them into a DOM element node
foreach (new \FluentDOM\XMLReader\SiblingIterator($reader, 'person') as $person) {
  /** @var \FluentDOM\DOM\Element $person */
  // ignore "Bob"
  if ($person('string(name)') !== 'Bob') {
    // write expanded node to the output
    $writer->collapse($person);
  }
}

$writer->endElement();
$writer->endDocument();

输出:

<?xml version="1.0"?>
<persons>
 <person>
  <name>Alice</name>
 </person>
 <person>
  <name>Charlie</name>
 </person>
</persons>