2015-11-06 71 views
0

我有xml文件。如何从XML中的foreach中删除?

<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'); 
+0

只是建立一个ID数组在循环。如果该ID已经在数组中,则可以将其删除。 – rjdown

+0

当我使用unset($ yml-> shop-> categories);它的工作很好,但是当我使用unset($ yml-> shop-> offers-> offer [$ sravnit]);没什么作用...( – user1837120

回答

0

这句法不作多种方式的意义:

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

  2. 你不能用$sravnit这样的ID选择<offer>。这是错误的。
    相反SimpleXml会在这样的列表中选择ñ节点:

    <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良好的深入论证。

在你的情况,你可能会首先检查在<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); 
    

    将返回具有索引= id和value的数组=计数:

    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:DELET Ë所有<offer>他们id属性在$ids
我会用xpath()选择的节点,unset()将其删除:

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

看到它在行动:https://eval.in/464608

+0

太棒了,我无法对你的帮助表示感谢,Thx! – user1837120