Невозможно изменить значение xml с помощью PHP

Это мой XML-файл:

<todos> <todo> <titel>sasd</titel> <erstellt>2012-04-30 17:19:21</erstellt> <erledigen_bis>2012-05-03</erledigen_bis> <erledigt>Nein</erledigt> <thingstodo>sffsdfdf</thingstodo> </todo> </todos> 

Теперь я хочу изменить значение внутри <erledigt> на «Ja».

Я пробовал это со следующим кодом:

 <?php $filename = 'xml/todos.xml'; $xmlDoc = new DOMDocument(); $xmlDoc->load('xml/todos.xml'); $todos = $xmlDoc->getElementsByTagName('todo'); foreach ($todos as $todo) { $titel = $todo->getElementsByTagName('titel'); $actualTitel = $titel->item(0)->nodeValue; $paramTitel = $_GET["titel"]; $erstellt = $todo->getElementsByTagName('erstellt'); $actualTimestamp = $erstellt->item(0)->nodeValue; $paramTimestamp = $_GET["timestamp"]; if ($paramTitel == $actualTitel && $paramTimestamp == $actualTimestamp) { $todo->erledigt= 'Ja'; } } $xmlDoc->save($filename); header('Location: todo.php'); ?> 

Пожалуйста, помогите мне, я искал около 5 часов в Интернете и не нашел решения для моей проблемы.

$todo->erledigt не работает в DOMDocument, только SimpleXML может это сделать. Вам нужно снова использовать getElementsByTagName .

Вам также нужно использовать nodeValue для получения / установки значения элемента.

 if ($paramTitel == $actualTitel && $paramTimestamp == $actualTimestamp) { $todo->getElementsByTagName('erledigt')->item(0)->nodeValue = 'Ja'; } 

ДЕМО: http://codepad.org/xJbQmO2u

Поскольку вы ищете определенные элементы внутри документа, я предлагаю вам найти их с помощью xpath:

 $xp = new DOMXPath($doc); $expression = sprintf('//todo[titel = "%s" and erstellt = "%s"]/erledigt', $_GET["titel"], $_GET["timestamp"]); $result = $xp->query($expression); foreach ($result as $node) { $node->nodeValue = 'Ja'; } 

Это приводит к следующему (примерному) выражению xpath:

 //todo[titel = "sasd" and erstellt = "2012-04-30 17:19:21"]/erledigt 

Который выберет все узлы erledigt которые являются частью todo узла, который имеет значения узла titel и erstellt как указано.

Затем вы можете легко изменить его. Кроме того, вы ищете узлы erledigt которые еще не «erledigt», но текущий вариант уже не повредит.

Пример демо / полного кода :

 <?php /** * @link http://stackoverflow.com/q/10388661/367456 */ $_GET["titel"] = 'sasd'; $_GET["timestamp"] = '2012-04-30 17:19:21'; $xml = '<todos> <todo> <titel>sasd</titel> <erstellt>2012-04-30 17:19:21</erstellt> <erledigen_bis>2012-05-03</erledigen_bis> <erledigt>Nein</erledigt> <thingstodo>sffsdfdf</thingstodo> </todo> </todos>'; $doc = new DOMDocument(); $doc->loadXML($xml); $xp = new DOMXPath($doc); $expression = sprintf('//todo[titel = "%s" and erstellt = "%s"]/erledigt', $_GET["titel"], $_GET["timestamp"]); $result = $xp->query($expression); foreach ($result as $node) { $node->nodeValue = 'Ja'; } echo $doc->saveXML(); 

Вам нужно отредактировать элемент <erledigt> , используя методы и свойства DOM для доступа к нему. Похоже, вы смешиваете его с SimpleXML.

 $todo->getElementsByTagName('erledigt')->item(0)->nodeValue = 'Ja'; 

Если вы хотите взглянуть на использование SimpleXML, то весь ваш код может выглядеть примерно так.

 <?php $paramTitel = $_GET["titel"]; $paramTimestamp = $_GET["timestamp"]; $todos = simplexml_load_file('xml/todos.xml'); foreach ($todos->todo as $todo) { if ($paramTitel == (string) $todo->titel && $paramTimestamp == (string) $todo->erstellt ) { $todo->erledigt = 'Ja'; } } $todos->asXML($filename); // Where does $filename come from? header('Location: todo.php'); ?> 

Чтение:

  • Использование SimpleXML и примеры
  • DOMDocument :: getElementsByTagName ()
  • DOMNodeList :: пункт ()
  • DOMNode :: nodeValue