Пробовал множество примеров на SO, но ни один из них не работал.
Цель: удалить узел (Ед. изм) и его дочерние элементы с помощью определенного id =
filename.xml
<archive>
<unit id = "0424670018">
<data>Blah blah blah #1</data>
<gdate>2018-05-28 00:42:46</gdate>
</unit>
<unit id = "0450170018">
<data>Blah blah blah #2</data>
<gdate>2018-05-28 00:45:01</gdate>
</unit>
</archive>
Используемый код, не знаю, почему он не работает при загрузке:
$id = '0450170018';
$file = 'filename.xml';
$xml = simplexml_load_string($file);
foreach($xml->archive as $fileload){
if ($fileload->unit['@id'] == $id){
$dom = dom_import_simplexml($fileload);
$dom->parentNode->removeChild($dom);
}
}






Вам необходимо использовать класс "DOMDocument"
$doc = new DOMDocument;
$doc->load('filename.xml');
$xml = $doc->documentElement;
$id = '0450170018';
$domNodeList = $xml->getElementsByTagname('unit');
foreach ( $domNodeList as $domElement ) {
$valueID = $domElement->getAttribute('id');
if ($valueID == $id)
{
$xml->removeChild($domElement);
}
}
$doc->save('filename.xml');
@ThW Я буду удалять только один узел за раз с помощью формы удаления, публикуя $ id, так что до сих пор это было успешно. Я собираюсь протестировать и ваш код, а затем принять решение. Спасибо.
Вы можете получить узел с помощью Xpath. Это позволяет напрямую получить соответствующие узлы.
$id = '0450170018';
$document = new DOMDocument();
$document->load('filename.xml');
$xpath = new DOMXpath($document);
foreach ($xpath->evaluate("//unit[@id='$id']") as $unitNode) {
$unitNode->parentNode->removeChild($unitNode);
}
$document->save('filename.xml');
Это тоже хорошо работает, и ваш контраргумент выше заставил меня выбрать эту версию. Спасибо.
Будьте осторожны,
getElementsByTagname()возвращает «живой» результат (он меняется, если вы изменяете DOM). Если вы удалите несколько узлов, это может работать не так, как ожидалось.