Как удалить тег XML на основе дочернего атрибута с помощью php?
У меня есть XML как ниже
<entries>
<entry>
<title lang="en">Sample</title>
<entrydate>0</entrydate>
<contents>0</contents>
<entrynum>0</entrynum>
</entry>
<entry>
<title lang="fr">Sample</title>
<entrydate>1</entrydate>
<contents>1</contents>
<entrynum>1</entrynum>
</entry>
</entries>
Есть ли в PHP способ удалить родительский узел (entry
) на основании названия lang
атрибут? Мне нужно оставить только en
один, поэтому в этом случае мне нужно будет получить XML без второго entry
узел.
Я попытался осмотреться, но не смог найти решения...
3 ответа
Вам нужно использовать DOMDocument
класс для разбора строки в документ XML. Тогда используйте DOMXpath
класс, чтобы найти целевой элемент в документе и использовать DOMNode::removeChild()
удалить выбранный элемент из документа.
$doc = new DOMDocument();
$doc->loadXML($xml);
$xpath = new DOMXpath($doc);
// select target entry tag
$entry = $xpath->query("//entry[title[@lang='fr']]")->item(0);
// remove selected element
$entry->parentNode->removeChild($entry);
$xml = $doc->savexml();
Вы можете проверить результат в демо
Вы также можете прочитать ваш файл и сгенерировать новый с вашей модификацией
<?php
$entries = array('title' => "What's For Dinner",
'link' => 'http://menu.example.com/',
'description' => 'Choose what to eat tonight.');
print "<entries>\n";
foreach ($entries as $element => $content) {
print " <$element>";
print htmlentities($content);
print "</$element>\n";
}
print "</entries>";
?>
Используйте метод, описанный в этом ответе, т.е.
<?php
$xml = simplexml_load_file('1.xml');
$del_items = [];
foreach ($xml->entry as $e) {
$attr = $e->title->attributes();
if ($attr && $attr['lang'] != 'en') {
$del_items []= $e;
}
}
foreach ($del_items as $e) {
$dom = dom_import_simplexml($e);
$dom->parentNode->removeChild($dom);
}
echo $xml->asXML();
Выход
<?xml version="1.0" encoding="UTF-8"?>
<entries>
<entry>
<title lang="en">Sample</title>
<entrydate>0</entrydate>
<contents>0</contents>
<entrynum>0</entrynum>
</entry>
</entries>
Элементы не могут быть удалены в первом цикле, потому что в противном случае мы можем разорвать цепочку итераций. Вместо этого мы собираем входные объекты в $del_items
массив, а затем удалить их из XML в отдельном цикле.