如何在foreach中从xml中删除?

时间:2015-11-06 01:04:17

标签: php xml unset

我有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'); 

1 个答案:

答案 0 :(得分:0)

这种语法在多种方面没有意义:

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

  2. 您无法选择ID为<offer>的{​​{1}}。这是错误的。
    相反,$sravnit将在列表中选择 n th 节点,如下所示:

    SimpleXml

    <drinks> <drink id="2">beer</drink> <drink id="5">wine</drink> <drink id="0">water</drink> </drinks> echo $xml->drink[2];,对不起。检查一下:https://eval.in/464564
    建议阅读http://php.net/manual/en/simplexml.examples-basic.php

  3. 使用water:请参阅此回答Remove a child with a specific attribute, in SimpleXML for PHP,详细了解如何合并unset()xpath()以删除特定节点{ {1}}。

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

    第1步:非唯一ID列表

    1. 使用SimpleXml创建一个包含所有id值的数组,如下所示:

      <offer>
    2. xpath()是一个$ids = $yml->xpath("//offer/@id"); - 元素数组,使用$ids转换为整数值:

      SimpleXml
    3. 获取数组array_map()非唯一值:

      $ids = array_map("intval", $ids);
      

      将返回一个index = id和value = count:

      的数组
      $ids
    4. 唯一ID的值为1,所以让我们删除所有这些:

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

      array(3) {
        [41850]=>int(3)
        [77777]=>int(1)
        [41340]=>int(1)
      }
      

      结果如下:

      $ids = array_diff($ids, array(1));
      
    6. 总结:让我们分两行写下以前的所有步骤:

      $ids = array_flip($ids);
      
    7. 第2步:删除array(1) { [3]=>int(41850) } 中所有$ids = $yml->xpath("//offer/@id"); $ids = array_flip(array_diff(array_count_values(array_map("intval", $ids)), array(1))); 属性的所有<offer>
      我将使用id来选择节点,并$ids将其删除:

      xpath()

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