2015-11-06 85 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