Intereting Posts
Ошибка Количество столбцов не совпадает со значением в строке 1? Должен ли я или не использовать методы getter и setter? Codeigniter Cart – сохранение данных в базе данных – как подойти? Как перенаправить с HTTPS на HTTP? Как удалить значения из массива в PHP? Создание эскизов из swf-файла в php? Сравнить объект с свойствами datetime без микросекунд Найти каждое воскресенье между двумя датами Манипулировать архивом в памяти с помощью PHP (без создания временного файла на диске) php mail () Идет спам, но когда он отправляется через SMTP-сервер, он работает нормально? Вызов функции-члена bindParam () для не-объекта ExtJS 4.2 – Возможные причины предупреждения о синхронном XMLHttpRequest? Нужно ли устанавливать mysql на AWS EC2, если я использую AWS rds в качестве экземпляра базы данных? Laravel: Difference App :: bind и приложение :: singleton Как отправить октет / поток типа BLOB типа на сервер с помощью AJAX?

Выбрать узел на основе атрибута и изменить поднод

У меня есть следующий XML-файл:

<?xml version="1.0" encoding="UTF-8"?> <programmedata> <programme id="1"> <name>Left</name> <image_path></image_path> <rating_point>0</rating_point> <five_star>0</five_star> 

С помощью следующего кода я пытаюсь изменить значение rating_point:

 $xml=simplexml_load_file("content.xml"); if(!empty($_POST["rating"]) && !empty($_POST["voted_programme"])){ try{ $rating = $_POST["rating"]; $i = $_POST['voted_programme']; $xml->programme[$i]->rating_point = $rating; if($rating == '5') { $xml->programme[$i]->five_star = $rating; } 

но получение ошибки:
Notice: Indirect modification of overloaded element of SimpleXMLElement has no effect in ...

попробовал другое решение, но, похоже, не работает.

Ваш оператор $xml->programme[1]->rating_point не выбирает узел <programme> с атрибутом id="1" .
Он ссылается на второй узел <programme> в вашем XML, независимо от его атрибута id .

Есть в основном 2 способа добраться до <programme id="1"> :

 $xml = simplexml_load_string($x); // assume XML in $x $rating = 5; $id = 1; 

# 1 зацикливание всего XML

 foreach ($xml->programme as $item) { if ($item[`id`] == $id) { $item->rating_point = $rating; if ($rating == 5) $item->five_star = $rating; } } 

Комментарий: см. Строку 2 ( if... ) о том, как обращаться к атрибутам.
см. работу: https://eval.in/458300

# 2 выберите с помощью xpath :

 $item = $xml->xpath("//programme[@id='$id']")[0]; if (!is_null($item)) { $item->rating_point = $rating; if ($rating == 5) $item->five_star = $rating; } 

Комментарии:

  • //programme : выберите каждый узел <programme> , где бы ни было в дереве XML
  • [@id='1'] : условие, @ для атрибута
  • функция xpath возвращает массив элементов SimpleXML , а [0] мы захватываем первый элемент в этом массиве и помещаем его в $item .

см. работу: https://eval.in/458310

Как вы можете видеть, решение №2 выполняется быстрее, тем более, если ваш XML содержит несколько узлов <programme> .