массивы — Использование unset () для удаления узла в XML; PHP / simplexml_load_file

Я пытаюсь использовать unset() удалить узел в XML с помощью PHP и не может понять, что здесь происходит. Кажется, он работает неправильно, и я видел здесь много других вопросов подобного характера, но, похоже, они не решают эту проблему напрямую. Вот как выглядит мой XML:

<?xml version="1.0" encoding="UTF-8"?>
<data>
<user>
<name>Test Name 1</name>
<email>[email protected]</email>
<spouse/>
</user>
<user>
<name>Test Name 2</name>
<email>[email protected]</email>
<spouse>Test Name 3</spouse>
</user>
</data>

Мой цикл, который я использую, выглядит следующим образом:

url = 'data/users.xml';
$xml = simplexml_load_file($url);

foreach($xml->user as $theUser){
if($theUser->email[0]=="[email protected]"){
echo "test";
unset($theUser);
}
}

Когда электронное письмо совпадает с «[email protected]», я хочу иметь возможность удалить все это user узел. Кажется, что это должно работать, но я не могу понять, почему это не будет? Любая помощь будет принята с благодарностью. Спасибо!

2

Решение

SimpleXML хорошо, не нужно переключаться на DOM, unset() работает нормально, если вы все делаете правильно:

unset($theUser[0]);

увидеть это работает: https://eval.in/228773

Однако будет проблема с вашим foreach() если вы удалите узел в середине цикла.

Я предлагаю использовать xpath() вместо цикла, IMO элегантный и код гораздо проще.

$users = $xml->xpath("/data/user[email='[email protected]']");

создаст массив всех <user> с этим адресом электронной почты.

unset($users[0][0]);

удалит первого пользователя в этом массиве.

foreach ($users as $user) unset($user[0]);

удалит весь массив.

увидеть это в действии: https://eval.in/228779

2

Другие решения

SimpeXML не предназначен для перехода на структуру XML. Просто простой способ чтения XML.

Если вы хотите манипулировать структурой XML, вы должны использовать Дом функции и более конкретно dom_import_simplexml. Эта функция позволяет импортировать элемент SimpleXML и превратить его в DOMElement это может быть использовано для манипуляции и включает в себя удаление.

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

<?php

$xmlData = '<?xml version="1.0" encoding="UTF-8"?>
<data>
<user>
<name>Test Name 1</name>
<email>[email protected]</email>
<spouse/>
</user>
<user>
<name>Test Name 2</name>
<email>[email protected]</email>
<spouse>Test Name 3</spouse>
</user>
</data>';

$xml = simplexml_load_string($xmlData);

foreach($xml->user as $theUser){
if($theUser->email == '[email protected]'){
$dom = dom_import_simplexml($theUser);
$dom->parentNode->removeChild($dom);
}
}

echo $xml->asXml();

При чтении этого кода вы можете подумать, почему это работает, поскольку мы не сохраняем новую структуру нигде после того, как выполнили RemoveChild функция. Это работает, потому что функции DOM не создают копии базовых объектов, а вместо этого управляют ими напрямую.

Результат

<?xml version="1.0" encoding="UTF-8"?>
<data>
<user>
<name>Test Name 2</name>
<email>[email protected]</email>
<spouse>Test Name 3</spouse>
</user>
</data>
3

По вопросам рекламы [email protected]