Удалить узел из файла XML при чтении его с помощью XmlReader?

У меня есть скрипт, который читает XML узел за узлом, используя XMLReader:

$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 после прочтения чтобы избежать повторного чтения одних и тех же данных при повторном вызове скрипта. Каков наилучший способ сделать это? Могу ли я сделать это во время чтения файла?

Я не мог найти ответ где-либо еще.

0

Решение

У XMLReader есть партнер по имени XMLWriter. Таким образом, для больших XML-файлов вы читаете XML-файл с использованием XMLReader, а записываете отфильтрованные / измененные данные с использованием XMLWriter в новый файл.

Расширение части файла в DOM позволяет легче читать и модифицировать эту часть, но вам нужно будет использовать XMLWriter для сериализации структуры XML в новый файл.

Я реализовал функции (в том числе collapse() метод) для этого в FluentDOM. Вот пример использования:

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

Другие решения

Вы не можете редактировать документ, читая его … по крайней мере без большого грязного неэффективного кода.

Лучший подход будет:

1) Читайте весь документ в секунду DOMDocument объект.

2) Когда вы читаете узлы один за другим из вашего XMLReader входной поток, найти соответствующие узлы в DOMDocument и удалите их после того, как вы закончите. Будьте осторожны, чтобы не удалять узлы, у которых есть дети, которых вы еще не просмотрели.

3) Когда закончите, сохраните новый DomDocument к новому имени файла и используйте его в качестве источника ввода для следующего сеанса редактирования.

Вы будете экспертом по DomDocument манипуляция, когда вы закончите.

Опубликовать новый вопрос, если у вас возникнут проблемы.

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector