Я немного смущен относительно того, как я могу удалить родительский узел чего-то, что я могу найти через поиск по 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, если на то пошло. Вы знаете, какие инструменты вы используете для таких сценариев.
Я думаю, что это не только решает вашу проблему, но, вероятно, помогает вам легче читать и понимать. Тем не менее, вы не уверены в производительности. Расскажите, сколько узлов вы регулярно работаете.