2013-04-09 108 views
1

我想刪除比今天早的任務,但我無法完全弄清楚如何從XML文件中刪除元素。PHP從XML中刪除元素

$xml_file = simplexml_load_file('file.xml');  
foreach ($xml_file->task as $aTask) { 
     if ($aTask->date < $today) { 
      //$xml_file->removeChild($aTask); //doesnt work 
     } 
} 

這裏是我下面的XML文件:

<?xml version="1.0"?> 
<calender> 
<task><date>00/00/0000</date><title>My Birthday</title><description>Today is my birthday!</description></task><task><date>04/01/2013</date><title>ghh</title><description>jfhjhj</description></task><task><date>04/01/2013</date><title>egfwe</title><description>wefwef</description></task><task><date>04/01/2013</date><title>cvbhm</title><description>dhmdh</description></task><task><date>04/02/2013</date><title>gg</title><description>gg</description></task><task><date>04/02/2013</date><title>test</title><description>test</description></task><task><date>04/03/2013</date><title>ggg</title><description>ggg</description></task><task><date>04/03/2013</date><title>ssdv</title><description>ssdvs</description></task><task><date>04/03/2013</date><title>test</title><description>testtest</description></task><task><date>04/04/2013</date><title>tttt</title><description>ttttttttt</description></task><task><date>04/05/2013</date><title>qewerbqwer</title><description>bwerbwerbwebr</description></task><task><date>04/07/2013</date><title>fgj</title><description>fghj f</description></task><task><date>04/08/2013</date><title>test</title><description>swdefswde</description></task><task><date>04/09/2013</date><title>hj,h</title><description>hj,gh</description></task><task><date>04/16/2013</date><title>dfbd</title><description>dfbdfb</description></task><task><date>04/17/2013</date><title>dfb</title><description>dfb</description></task> 
</calender> 

有人可以幫我嗎?

+0

你可以顯示'$ aTask-> date'和'$ today'包含什麼? – 2013-04-09 16:10:24

回答

3

使用simplexml: - >現場演示@http://codepad.viper-7.com/Jl16Oh

$xml = simplexml_load_string($x); // XML is in $x 

$today = date("m/d/Y"); 
$max = $xml->task->count()-1; 

for ($i = $max; $i >=0; $i--) { 

    if ($xml->task[$i]->date < $today) unset($xml->task[$i]); 

} 
+0

說明:向後循環,因此索引在刪除節點後保持不變。這是答案很好。 – 2013-04-09 16:33:22

+0

非常感謝! – Void 2013-04-09 17:01:07

+0

@ michi,我不得不說它很乾淨。 +1! – 2013-04-09 17:04:44

1

我認爲比較日期就好像它是一種實現的數據類型一樣是有問題的。

用你的算法,你正在比較字符串,這不是你想要的。您可以使用的preg_match獲得天,月,年,然後mktime比較時間戳:

http://php.net/manual/en/function.preg-match.php

http://php.net/manual/en/function.mktime.php

編輯:你甚至可以做,沒有的preg_match,這是費時。下面是一個例子鑄造你的對象到一個數組(你要投一個這樣或那樣的,你也可以選擇使用DOM,請參閱:Remove a child with a specific attribute, in SimpleXML for PHP

<? 
$xml_file = (array)simplexml_load_file("file.xml")or die('Error reading XML file'); 
print_r($xml_file); 

$today=array(
    'day' => intval(date('d')), 
    'month' => intval(date('m')), 
    'year' => intval(date('Y')), 
    ); 
//print_r($today); 

foreach($xml_file['task'] as $key=>$aTask) { 
     $date = (string)$aTask->date; 
     $month = intval($date[0].$date[1]); 
     $day = intval($date[3].$date[4]); 
     $year = intval($date[6].$date[7].$date[8].$date[9]); 
     //echo $aTask->title.': '.$month.'/'.$day.'/'.$year."\n"; 
     if (($year < $today['year']) || ($year==$today['year'] && $month < $today['month']) || ($year==$today['year'] && $month == $today['month'] && $day < $today['day'])) { 
      //echo 'Deleting '.$aTask->title."\n"; 
      unset($xml_file['task'][$key]); 
     } 
} 

// Inspired from: https://stackoverflow.com/questions/1397036/how-to-convert-array-to-simplexml 
$xml = '<?xml version="1.0"?>'."\n".'<calendar>'; 
function addChild($item) { global $xml; $xml.=$item->asXML(); } 
array_walk_recursive($xml_file['task'], 'addChild'); 
$xml .= '</calendar>'; 
//echo $xml; 
file_put_contents('out.xml', $xml); 
?> 
+0

我已經試過了你的代碼,但是無法通過'$ xml_file ['task']',這會觸發'Warning:爲foreach()'提供的無效參數。 – 2013-04-10 07:16:30

+0

您是否嘗試過完全相同的代碼,包括轉換爲數組?因爲它對我有用。也許你有一箇舊版本的PHP呢? – 2013-04-10 07:20:37

+0

哦,對不起,我忽略了'(數組)'位。然後,我認爲您應該澄清如何獲取XML代碼,因爲它不是很明顯。 – 2013-04-10 07:46:42

1

這實際上非常棘手。您必須unset()適當的變量,但它需要是對父節點的引用(即unset($aTask)將不起作用)。此外,如果您使用foreach ($xml_file->task as $index => $aTask)來跟蹤孩子的位置,則在每次迭代中都會得到task

你需要一些醜陋的代碼是這樣的:

$index = 0; 
$remove = array(); 
foreach ($xml_file->task as $aTask) { 
    if ($aTask->date < $today) { 
     $remove[] = $index; 
    } 
    $index++; 
} 

foreach($remove as $index){ 
    unset($xml_file->task[0]); 
} 

附:如前所述,您的日期處理例程不起作用。

編輯:我其實試圖我自己的代碼和it works,所以downvoter應該解釋自己。