У меня есть следующий 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>
.