PHP SimpleXML – удалить узел xpath

Я немного смущен относительно того, как я могу удалить родительский узел чего-то, что я могу найти через поиск по xpath:

$xml = simplexml_load_file($filename); $data = $xml->xpath('//items/info[item_id="' . $item_id . '"]'); $parent = $data[0]->xpath("parent::*"); unset($parent); 

Таким образом, он находит идентификатор элемента, никаких проблем нет, но unset не избавляется от этого узла <items> . Все, что я хочу сделать, это удалить <items>...</items> для этого продукта. Очевидно, что в XML-файле есть множество узлов <items> поэтому он не может удалить unset($xml->data->items) поскольку это удалит все.

Любые идеи очень ценятся 🙂

 <?php $xml = new SimpleXMLElement('<a><b/></a>'); unset($xml->b); echo $xml->asxml(); с <?php $xml = new SimpleXMLElement('<a><b/></a>'); unset($xml->b); echo $xml->asxml(); 

это работает по назначению (удаление элемента <b /> из документа), потому что вызывается метод __unset () (или эквивалент в коде модулей).
Но когда вы вызываете unset($parent); он удаляет только ссылку на объект, хранящуюся в $ parent, но не влияет на сам объект или документ, хранящийся в $ xml. Для этого я вернусь к DOMDocument .

 <?php $doc = new DOMDOcument; $doc->loadxml('<foo> <items> <info> <item_id>123</item_id> </info> </items> <items> <info> <item_id>456</item_id> </info> </items> <items> <info> <item_id>789</item_id> </info> </items> </foo>'); $item_id = 456; $xpath = new DOMXpath($doc); foreach($xpath->query('//items[info/item_id="' . $item_id . '"]') as $node) { $node->parentNode->removeChild($node); } echo $doc->savexml(); 

печать

 <?xml version="1.0"?> <foo> <items> <info> <item_id>123</item_id> </info> </items> <items> <info> <item_id>789</item_id> </info> </items> </foo> 

Это работает для меня. Не unset($parent); но unset($parent[0]); :

 $res = $xml->xpath('//key/k[. = "string"]/parent::*'); $parent = $res[0]; unset($parent[0]); 

Это работает путем создания саморекламы к элементу simplexml в $parent (или $res[0] ).

Более подробное объяснение см. В соответствующем ответе в связанном вопросе. Удалите дочерний элемент с определенным атрибутом в SimpleXML для PHP .

Один из способов – импортировать узел SimpleXML в DOMDocument, а затем удалить в DOMDocument. Не очень прямо, но он работает:

 $xml = simplexml_load_file($filename); $result = $xml->xpath("/cardsets/cardgroup"); foreach ($result as $el) { if ($el['id'] == $id) { $domRef = dom_import_simplexml($el); $domRef->parentNode->removeChild($domRef); $dom = new DOMDocument('1.0'); $dom->preserveWhiteSpace = false; $dom->formatOutput = true; $dom->loadXML($xml->asXML()); $dom->save($filename); break; } } 

Я бы наверняка подошел к этой проблеме как к фильтрующей, а не к удаленной.

Таким образом, копирование необходимых узлов в другую строку или создание другого документа XML, если на то пошло. Вы знаете, какие инструменты вы используете для таких сценариев.

Я думаю, что это не только решает вашу проблему, но, вероятно, помогает вам легче читать и понимать. Тем не менее, вы не уверены в производительности. Расскажите, сколько узлов вы регулярно работаете.