使用 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>
我有一个脚本使用 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>