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

Я не мог найти ответа больше нигде.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
0
636
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Лучшим подходом было бы:

1) Прочтите весь документ во второй объект DOMDocument.

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

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

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

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

Я бы предпочел не зачитывать каждый раз весь документ в память. Я также надеялся, что это можно будет сделать без создания новых файлов. Спасибо за ваш ответ!

Dave 09.11.2018 11:41

Что ж, это неизбежно, и ThW создал впечатляющий набор инструментов для FluentDom!

bcperth 09.11.2018 23:37
Ответ принят как подходящий

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

Другие вопросы по теме