【问题标题】:Can't changing an xml value with PHP无法使用 PHP 更改 xml 值
【发布时间】:2012-04-30 18:27:43
【问题描述】:

这是我的 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>

现在我想将&lt;erledigt&gt; 标记内的值更改为“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 个小时,找不到任何解决我的问题的方法。

【问题讨论】:

    标签: php xml dom


    【解决方案1】:

    $todo-&gt;erledigt 在 DOMDocument 中不起作用,只有 SimpleXML 可以做到。您需要再次使用getElementsByTagName

    您还需要使用nodeValue 来获取/设置元素的值。

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

    演示:http://codepad.org/xJbQmO2u

    【讨论】:

    • 非常感谢,你把我从一个不眠之夜救了出来!
    【解决方案2】:

    当您在文档中查找特定元素时,我强烈建议您使用 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
    

    这将选择属于todo 节点的所有erledigt 节点,这些节点具有指定的titelerstellt 节点值。

    然后您可以轻松更改它。此外,您正在寻找erledigt 尚未“erledigt”的节点,但当前的变体已经没有伤害。

    Demo/Full Code Example:

    <?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();
    

    【讨论】:

    • 我不认为通过 XPath 向无法确定使用哪个 XML 扩展的人介绍搜索是一个好主意。
    • TS 使用 DOMDocument,所以我选择了“那个”xpath,它与具有 xpath 的 simple-xml 同样简单(同样的表达式也简化了 simplexml 代码)。
    • 我在整个下午的研究中都阅读了一些关于 XPath 的东西,但这对我来说太复杂了,因为这是我第一个使用 XML、PHP 和 JS 的项目,所以我真的处于起步阶段我的网络开发之旅。但是很高兴看到使用 XPath 的解决方案,感谢您提供有趣但也很复杂的东西 ;)
    • @alderos:不客气。无论您是刚刚开始还是已经这样做多年,总有一些东西要学习。 ;)
    【解决方案3】:

    您需要编辑&lt;erledigt&gt; 元素,使用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');
    
    ?>
    

    阅读:

    【讨论】:

    • 在复制和粘贴之前,我想更正值而不是 $filename,但我只是删除了它,以后没有编辑它,如果我混淆了你,对不起。 SimpleXML 解决方案非常好,做得很好,谢谢。
    猜你喜欢
    • 2014-10-17
    • 1970-01-01
    • 1970-01-01
    • 2011-05-30
    • 1970-01-01
    • 1970-01-01
    • 2011-03-24
    • 2015-03-20
    • 1970-01-01
    相关资源
    最近更新 更多