【问题标题】:Using unset() to delete node in XML; PHP/simplexml_load_file使用 unset() 删除 XML 中的节点; PHP/simplexml_load_file
【发布时间】:2015-01-28 11:50:22
【问题描述】:

我正在尝试使用unset() 使用 PHP 删除 XML 中的一个节点,但无法弄清楚这里发生了什么。它似乎无法正常工作,我在这里看到了很多类似性质的其他问题,但他们似乎没有直接解决这个问题。这是我的 XML 的样子:

<?xml version="1.0" encoding="UTF-8"?>
<data>
    <user>
        <name>Test Name 1</name>
        <email>test@test.com</email>
        <spouse/>
    </user>
    <user>
        <name>Test Name 2</name>
        <email>anotherone@test.com</email>
        <spouse>Test Name 3</spouse>
    </user>
</data>    

我正在使用的循环是这样的:

url = 'data/users.xml';
$xml = simplexml_load_file($url);

foreach($xml->user as $theUser){
    if($theUser->email[0]=="test@test.com"){
        echo "test";
        unset($theUser);
    }
}

当电子邮件匹配“test@test.com”时,我希望能够删除整个user 节点。似乎这应该有效,但我不知道为什么它不会?任何帮助将不胜感激。谢谢!

【问题讨论】:

    标签: php arrays xml unset


    【解决方案1】:

    SimpleXML 很好,不需要切换到DOMunset() 工作正常,如果你做得对:

    unset($theUser[0]);
    

    看到它的工作:https://eval.in/228773

    但是,如果您在循环中删除节点,您的 foreach() 就会出现问题。

    我建议使用xpath() 而不是循环,IMO 优雅且代码更简单。

    $users = $xml->xpath("/data/user[email='test@test.com']");
    

    将使用该电子邮件地址创建一个包含所有 &lt;user&gt; 的数组。

    unset($users[0][0]);
    

    将删除该数组中的第一个用户。

    foreach ($users as $user) unset($user[0]);
    

    将删除整个数组。

    查看实际操作:https://eval.in/228779

    【讨论】:

    • 在示例链接中,它看起来效果很好,所以我喜欢这种方法,但我将如何从 URL 加载这个 XML。当我使用 URL(如 simplexml_load_string('data/users.xml'); )时,它一直给我一个错误,这是有道理的,因为它将 URL 作为字符串而不是路径读取。
    • 哎呀没关系,我只需要在 URL 路径上使用 file_get_contents()。为将来使用此功能的人添加答案可能会很好吗?感谢您的帮助!
    • @MillerMedia simplexml_load_file() 可以从文件中创建对象。
    【解决方案2】:

    SimpeXML 并不是真的要更改为 XML 结构。只是一种读取 XML 的简单方法。

    如果您想操作 XML 结构,您应该使用dom functions,更具体地说是dom_import_simplexml。此函数允许您导入 SimpleXML 元素并将其转换为可用于操作且包括删除的DomElement

    这是一个解决您的问题并演示 dom_import_simplexml 用法的代码示例。

    <?php
    
    $xmlData = '<?xml version="1.0" encoding="UTF-8"?>
    <data>
        <user>
            <name>Test Name 1</name>
            <email>test@test.com</email>
            <spouse/>
        </user>
        <user>
            <name>Test Name 2</name>
            <email>anotherone@test.com</email>
            <spouse>Test Name 3</spouse>
        </user>
    </data>';
    
    $xml = simplexml_load_string($xmlData);
    
    foreach($xml->user as $theUser){
        if($theUser->email == 'test@test.com'){
            $dom = dom_import_simplexml($theUser);
            $dom->parentNode->removeChild($dom);
        }
    }
    
    echo $xml->asXml();
    

    阅读此代码时,您可能会想为什么它会起作用,因为我们在执行removeChild 函数后没有将新结构保存在任何地方。这是因为 DOM 函数不会创建底层对象的副本,而是直接操作它们。

    结果

    <?xml version="1.0" encoding="UTF-8"?>
    <data>  
        <user>
            <name>Test Name 2</name>
            <email>anotherone@test.com</email>
            <spouse>Test Name 3</spouse>
        </user>
    </data>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-25
      • 2014-04-05
      • 1970-01-01
      • 1970-01-01
      • 2017-09-13
      相关资源
      最近更新 更多