Это мой 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'; }
Поскольку вы ищете определенные элементы внутри документа, я предлагаю вам найти их с помощью 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'); ?>
Чтение: