PHP Remove Element from XML

泪湿孤枕 提交于 2020-01-11 12:21:16

问题


I want to remove tasks that are older than today, but I can't quite figure out how to remove elements from XML file yet.

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

Here is my XML file below:

<?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>

can someone please help me?


回答1:


Using simplexml: --> live demo @ 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]);

}



回答2:


It's actually very tricky. You have to unset() the appropriate variable, but it needs to be a reference to the parent node (i.e., unset($aTask) will not work). Additionally, if you do foreach ($xml_file->task as $index => $aTask) to keep track of the child position, you'll get task in every iteration!

You need some ugly code like this:

$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]);
}

P.S. As already noted, your date handling routines do not work.

Edit: I've actually tried my own code and it works, so downvoter should explain himself.




回答3:


I think it is problematic to compare dates as if it was an implemented type of datas.

With your algorithm, you are comparing strings, which is not what you want. You can use preg_match to get day, month and year, then mktime to compare timestamps:

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

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

EDIT: You can even do that without preg_match, that is time consuming. Here is an example casting your object into an array (you have to cast one way or another, you can also select to use DOM, see: 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);
?>


来源:https://stackoverflow.com/questions/15907041/php-remove-element-from-xml

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!