在使用simpleXML处理XML文件节点值之后,如何在节点值中出现重复项时删除父节点?

时间:2017-09-10 10:56:31

标签: php xml

我的xml文件看起来像这样 - 我想(为了示例而简化)为每个节点值添加1,然后检查重复项。如果存在重复节点,我想删除父节点,然后返回all作为xml的唯一节点。

<?xml version="1.0" encoding="UTF-8"?>
<channel>
<item>
    <gid>1240</gid>
</item>
<item>
    <gid>1440</gid>
</item>
<item>
    <gid>1440</gid>
</item>
<item>
    <gid>246</gid>
</item>

所以我想要的输出是:

<?xml version="1.0" encoding="UTF-8"?>
<channel>
<item>
    <gid>1241</gid>
</item>
<item>
    <gid>1441</gid>
</item>
<item>
    <gid>247</gid>
</item>

我的代码看起来像这样 - 操作部分已经解决,但是我无法弄清楚如何检查新的是否重复,然后在将其作为XML返回之前删除它的父级。我认为将所有值作为数组存储在循环中是正确的但在此之后我会陷入困境。感谢任何帮助。

<?php

$xmllink = 'items.xml';

header("Content-type: text/xml");

$xml=simplexml_load_file($xmllink) or die("Error: Cannot create object");

$xml->channel;

foreach ($xml as $anything) {

// find the <gid>
$newgid = $anything->gid;

// manipulate <gid>
$anything->gid = $newgid +1;

// store all gid + 1 in array
$allgids[] = $newgid;}

echo $xml->asXML();

?>

1 个答案:

答案 0 :(得分:0)

当您想要更改文档的结构时,SimpleXML并不是很好。

但是你可以通过一些工作来做到这一点。首先,当您尝试同时迭代文档时,对文档的任何操作都很困难。这就是我使用XPath获取项目列表然后迭代该列表的原因。如果该项目已经存在,我使用unset()将其删除。 (更深入地阅读Remove a child with a specific attribute, in SimpleXML for PHP以获得有关其工作原理的完整答案。)

<?php 
error_reporting(E_ALL);
ini_set('display_errors', 1);

$xmlDoc = <<< XML
<?xml version="1.0" encoding="UTF-8"?>
<channel>
<item>
    <gid>1240</gid>
</item>
<item>
    <gid>1440</gid>
</item>
<item>
    <gid>1440</gid>
</item>
<item>
    <gid>246</gid>
</item>
</channel>
XML;

$xml = simplexml_load_string($xmlDoc);
$allgids = [];
$items = $xml->xpath("//item");
foreach ($items as $item) {

    // find the <gid>
    $newgid = $item->gid;
    // manipulate <gid>
    $item->gid = $newgid +1;
    if ( in_array($newgid, $allgids))   {
        unset($item[0]);
    }
    else    {
        // store all gid + 1 in array
        $allgids[] = (string)$newgid;
    }
}

echo $xml->asXML();

虽然在这个例子中我使用的是字符串中的代码,但如果你从文件中加载它,则同样适用。