Texan78 Posted June 4, 2013 Share Posted June 4, 2013 I have done a search but I can't really find anything related to what I am needing. I am not sure if I am searching for it correctly or not. I have an XML file that is created via PHP and populated with data from a form. What I am trying to do is delete certain entries in that XML file after X amount of time. Is there an easy way to do this or can it even be done at all. I was thinking of some php script that was run by a CRON to check the XML file and delete certain entries by the timestamp after X amount of time. Can someone provide some suggestions or get me pointed in the right direction? -Thanks! Quote Link to comment Share on other sites More sharing options...
Texan78 Posted June 4, 2013 Author Share Posted June 4, 2013 (edited) I can't edit my original post so I will just add it here. This is the code I have come up with but a little stuck. I was thinking of a php script that is run by a CRON that will load the XML and look for any entries older than 12 hours and remove them then resave the XML. Where I am stuck is I am not sure how set it to check for entries older than 12 hours. Am I on the right track? Any suggestions? <?php $doc = new DOMDocument; $doc->load('mesquite.xml'); $thedocument = $doc->documentElement; //this gives you a list of the reports $list = $thedocument->getElementsByTagName('reports'); //figure out which ones you want -- assign it to a variable (ie: $nodeToRemove ) $nodeToRemove = null; foreach ($list as $domElement){ $attrValue = $domElement->getAttribute('timestamp'); if ($attrValue == 'VALUEYOUCAREABOUT') { $nodeToRemove = $domElement; //will only remember last one- but this is just an example } } //Now remove it. if ($nodeToRemove != null) $thedocument->removeChild($nodeToRemove); echo $doc->saveXML(); ?> Here is an example of the XML <entrys> − <reports> <timestamp>Mon Jun 3rd 7:34 am</timestamp> <fname>Unknown</fname> <lname/> <location/> <report>WIND DAMAGE</report> <description>Enter report description</description> </reports> − <reports> <timestamp>Tue Jun 4th 12:02 pm</timestamp> <name/> <location>Mesquite</location> <report>GENERAL</report> <description>Test of the form input. </description> </reports> </entrys> Edited June 4, 2013 by Texan78 Quote Link to comment Share on other sites More sharing options...
Jessica Posted June 4, 2013 Share Posted June 4, 2013 (edited) Edit: Do the remove command within the loop. Not at the end. Edited June 4, 2013 by Jessica Quote Link to comment Share on other sites More sharing options...
requinix Posted June 4, 2013 Share Posted June 4, 2013 How often is the XML updated? Can you modify whatever reads it? Because you might be able to make the reader skip over old entries when displaying the contents, then make whatever updates it also remove old entries. No cron required. Quote Link to comment Share on other sites More sharing options...
Texan78 Posted June 5, 2013 Author Share Posted June 5, 2013 How often is the XML updated? Can you modify whatever reads it? Because you might be able to make the reader skip over old entries when displaying the contents, then make whatever updates it also remove old entries. No cron required. The XML is updated manually by persons who are submitting a storm report from a form on one of the pages. So there is really only data when there is a storm. Which is why I was wanting to delete it after certain amount of time so there isn't old reports just sitting there for weeks if there is no storms. I like that idea of no cron. It's not a big deal having to set up one though. I just figured having a separate file to remove entries then call it with a cron would be easier to keep the code separated. I am not sure how easy that would be to implement into the code that displays the data. This is what I have come up with so far but it's not removing anything. It should remove it all of it because it's all over an hour but it doesn't. <?php $doc = new DOMDocument; $doc->load('mesquite.xml'); $thedocument = $doc->documentElement; //this gives you a list of the reports $list = $thedocument->getElementsByTagName('reports'); //figure out which ones you want -- assign it to a variable (ie: $nodeToRemove ) $reports = null; foreach ($list as $domElement){ $timestamp = strtotime($domElement->getAttribute('timestamp')); if ($timestamp < strtotime('now - 1 hour')) { $reports = $domElement; //Now remove it. if ($reports != null) $thedocument->removeChild($reports); } } echo $doc->saveXML(); ?> When I run it this is what it's echo'ing http://www.mesquiteweather.net/xml/update.php Which seems to be adding entries. Here is the raw XML http://www.mesquiteweather.net/xml/mesquite.xml Quote Link to comment Share on other sites More sharing options...
cpd Posted June 5, 2013 Share Posted June 5, 2013 (edited) 2 issues: $timestamp = strtotime($domElement->getAttribute('timestamp')); 1) Timestamp is an element in your XML document, not an attribute. 2) Are you sure the date/time format you've stored in the XML is a valid date/time format as per the documentation http://uk1.php.net/manual/en/datetime.formats.php? It doesn't look like any of the valid ones to me, could be wrong though. Best thing to do is echo it out and see if it worked. Edited June 5, 2013 by cpd Quote Link to comment Share on other sites More sharing options...
Texan78 Posted June 5, 2013 Author Share Posted June 5, 2013 (edited) When I run it this is what it's echo'ing http://www.mesquiteweather.net/xml/update.php Timestamp is an element in your XML document, not an attribute True, but if you look at that line carefully it is "$domElement->getAttribute" and "$reports = $domElement;" which means it should be looking for the element "timestamp" then get the attribute of timestamp being the date/time. This is what's in the script that creates the data for the entries. $reports->addChild('timestamp', date("D M jS g:i a",time())); Edited June 5, 2013 by Texan78 Quote Link to comment Share on other sites More sharing options...
cpd Posted June 5, 2013 Share Posted June 5, 2013 (edited) Afraid not. Its actually looking for an attribute called "timstamp" in the "reports" nodes. So what its expecting is <reports timestamp="[some timestamp]"> ... </reports> Like I said before, "timestamp" is an element, not an attribute. No matter which node you try to select it from using the $node->getAttribute($name) method, it'll never get it, EVER, because its not an attribute. If you want the timestamp of the first "reports" node you need: $timestamp = $dom->getElementsByTagName("reports")->item(0)->getElementsByTagName("timestamp")->item(0)->textContent; Edited June 5, 2013 by cpd Quote Link to comment Share on other sites More sharing options...
cpd Posted June 5, 2013 Share Posted June 5, 2013 (edited) Reviewing that you can just do $root->getElementsByTagName("timestamp")->item(0)->textContent; but in your scenario you need the reports node as well. Edited June 5, 2013 by cpd Quote Link to comment Share on other sites More sharing options...
Texan78 Posted June 5, 2013 Author Share Posted June 5, 2013 (edited) I hear what you're saying and that makes sense. How it's suppose to work is it is suppose to check the timestamp. If it is X amount from the time now it is suppose to remove that report. This code is code I have found after doing extensive searching. I really haven't been able to find anything solid associated with what I need. So I have just been trying to piece together code from searches. That is what the line is code is suppose to do. It is just suppose to check the time as a qualifier. $timestamp = strtotime($domElement->getAttribute('timestamp')); if ($timestamp < strtotime('now - 1 hour')) { $reports = $domElement; When I echo the script it shows all the entries it should remove. It is just not removing them. http://www.mesquiteweather.net/xml/update.php <?php $doc = new DOMDocument; $doc->load('mesquite.xml'); $thedocument = $doc->documentElement; //this gives you a list of the reports $list = $thedocument->getElementsByTagName('reports'); //figure out which ones you want -- assign it to a variable (ie: $nodeToRemove ) $reports = null; foreach ($list as $domElement){ $timestamp = strtotime($domElement->getAttribute('timestamp')); if ($timestamp < strtotime('now - 1 hour')) { $reports = $domElement; //Now remove it. if ($reports != null) $thedocument->removeChild($reports); } } echo $doc->saveXML(); ?> Edited June 5, 2013 by Texan78 Quote Link to comment Share on other sites More sharing options...
Solution cpd Posted June 5, 2013 Solution Share Posted June 5, 2013 (edited) You're still not hearing me or thinking logically about this. $report->getAttribute("timestamp") will look for the "timestamp" attribute in each report node: <reports timestamp="[some timestamp]"> ... </reports> You want to get an element that's that's a child node of the "reports" tag and as such should grab it the same way as you would get the reports using $report->getElementByTagName("timestamp"): $reports = $root->getElementByTagName("reports"); foreach($reports as $report) { $timestamp = $report->getElementByTagName("timestamp")->item(0); // Code omitted } This now looks for the timestamp using the XML structure you have. Because I'm feeling nice, I wrote this script in 10 minutes by applying logical thought and reading the documentation. It removes the "reports" that are older than 1 hour: // Load the document $doc = new DOMDocument(); $doc->load('test.xml'); // Get the root node and timestamps $root = $doc->documentElement; $timestamps = $root->getElementsByTagName("timestamp"); // Define a variable for the current time $currentTime = strtotime("-1 hour"); // Define an array to hold the nodes we want to remove $remove = array(); // Cycle through each timestamp and determine if it was set more than 1 hour ago // If so add it to our remove array foreach($timestamps as $ts) { $time = strtotime($ts->textContent); if($time < $currentTime) { $remove[] = $ts->parentNode; } } // Remove all the nodes found foreach($remove as $node) { $root->removeChild($node); } // Save the document $doc->save("test.xml"); You'll notice I did it slightly differently than the way you were trying to do it. I just grabbed the timestamps and looped through them, when one is found that's older than 1 hour, it adds the parent node on to the remove array; the parent node being the "reports" node associated with that timestamp. Edited June 5, 2013 by cpd Quote Link to comment Share on other sites More sharing options...
Texan78 Posted June 5, 2013 Author Share Posted June 5, 2013 You're still not hearing me or thinking logically about this. Yes I do hear you as I clearly stated in my last post, first sentence, "I hear what you're saying and that makes sense". I was just trying to explain what I was trying to do so you would have better information and we were on the same page. It appears to be working as when I run the script it removed all the entries. I am running a test so I will know more in an about 30 mins. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.