根据属性选择节点并更改子节点


Select node based on attribute and change subnode

我有以下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 没有选择具有id="1"属性的<programme>节点。
它指的是XML中的第二个<programme>节点,不管它的id属性是什么。

基本上有两种方法可以到达<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 select with 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>节点,则更快。