如何从 foreach 中的 xml 中删除?

How can I delete from xml in foreach?

我有 xml 个文件。

<shop>
 <categories>
    <category id="132">kids</category>
    <category id="62" parentId="133">women</category>
    <category id="172" parentId="1">men</category>
</categories>

<materials>
    <material id="1">one</material>
    <material id="2">two</material>
    <material id="3">soon</material>
</materials>

<offers>

        <offer id="41850" available="true">
            <price>3220</price>
            <currencyId>EUR</currencyId>
            <date>2015-02-05</date>
        </offer>
        <offer id="41850" available="true">
            <price>3220</price>
            <currencyId>EUR</currencyId>
            <date>2015-02-05</date>
        </offer>
        <offer id="41850" available="true">
            <price>3220</price>
            <currencyId>EUR</currencyId>
            <date>2015-02-05</date>
        </offer>
    <offer id="77777" available="true">
            <price>3250</price>
            <currencyId>EUR</currencyId>
            <date>2015-02-05</date>
        </offer>
    <offer id="41340" available="true">
            <price>3120</price>
            <currencyId>EUR</currencyId>
            <date>2015-02-05</date>
        </offer>

我需要删除类别和资料。之后我需要删除所有不唯一的报价并将其写入新的 xml 文件。

我的问题。我无法删除非独特优惠。请帮我!谢谢。这是我的代码。

 $url = 'test.xml';
$yml = simplexml_load_file($url);  
unset($yml->shop->categories);     
unset($yml->shop->materials);      

$itemid = '0'; 

foreach ($yml->shop->offers->offer as $item){
    $sravnit = $item['id'];  
    if("$sravnit" == "$itemid") {
        echo "$sravnit eq $itemid delete<br>";
        unset($yml->shop->offers->offer[$sravnit]); 
        continue; 
    else {echo "$sravnit not eq $itemid ";
    $itemid = $sravnit;
    echo "itemid to - $itemid <br>"; 
    }


 }
$yml->asXML('odd.xml'); 

此语法在多个方面都没有意义:

unset($yml->shop->offers->offer[$sravnit]); 
  1. <shop> 是您的根节点,由 $yml.
    表示 所以路径是$yml->offers->offer

  2. 你不能像这样select ID 为$sravnit<offer>。错了。
    相反,SimpleXml 将 select nth 节点,如下所示:

    <drinks>
        <drink id="2">beer</drink>
        <drink id="5">wine</drink>
        <drink id="0">water</drink>
    </drinks>
    

    echo $xml->drink[2];water,对不起。查一下:https://eval.in/464564
    http://php.net/manual/en/simplexml.examples-basic.php 是推荐阅读。

  3. 使用 unset():请参阅此答案 Remove a child with a specific attribute, in SimpleXML for PHP 以深入了解如何组合 xpath()unset() 进行删除SimpleXml.

  4. 的特定节点

在您的情况下,您可能首先检查 <offer> 节点中的非唯一 ID 属性,然后在第二步中删除它们。

第 1 步:非唯一 ID 列表

  1. xpath() 创建一个包含所有 id 值的数组,如下所示:

    $ids = $yml->xpath("//offer/@id");
    
  2. $idsSimpleXml个元素的数组,用array_map()转成整数值:

    $ids = array_map("intval", $ids);
    
  3. 获取数组$ids非唯一值:

    $ids = array_count_values($ids);
    

    将return一个索引=id且值=count的数组:

    array(3) {
      [41850]=>int(3)
      [77777]=>int(1)
      [41340]=>int(1)
    }
    
  4. 唯一id的值为1,所以让我们删除所有这些:

    $ids = array_diff($ids, array(1));
    
  5. 现在你有一个包含所有非唯一 ID 的数组,让我们翻转索引和值:

    $ids = array_flip($ids);
    

    这是结果:

    array(1) {
      [3]=>int(41850)
    }
    
  6. 总结:让我们把前面的所有步骤写成两行:

    $ids = $yml->xpath("//offer/@id");
    $ids = array_flip(array_diff(array_count_values(array_map("intval", $ids)), array(1)));
    

步骤 #2:删除 $ids 中具有 id 属性的所有 <offer>
我将使用 xpath() 到 select 节点,并使用 unset() 删除它:

foreach ($ids as $id) {
    foreach ($xml->xpath("//offer[@id='$id']") as $item)
        unset ($item[0]);
}

查看实际效果:https://eval.in/464608