Jack
Jack

Reputation: 722

Using Python to change the date on an xml document

I have an xml in this form

<project name="Hello World">
        <testfile name="testfile1">
                <type>TXT</type>
                <size>1000</size>
                <lastModified>2014-08-03 03:40:00</lastModified>
        </testfile>
        <testfile name="testfile2">
                <type>PDF</type>
                <size>500</size>
                <lastModified>2015-09-23 17:40:17</lastModified>
        </testfile>
</project>

This is an .xml file containing info about my project, so I can update my testfiles should they are more than 3 months old.

Right now, i'm stuck trying to figure out how to change the element in the .xml file. This is my code so far...

import xml.etree.ElementTree as ET
import sys
from datetime import datetime
def updateLastModified(self):
        today = datetime.now().strftime('%Y-%m-%d %H:%M:%S') # This variable stores todays date and time stamp for future reference. We shouldn't compute a new one every time.
        today = datetime.strptime(today, '%Y-%m-%d %H:%M:%S') 
        # Now we need to iterate through all the testfiles in our metadata and update their lastModified tag with the current date.
        for testfile in self.getMetadataRoot().findall('testfile'):
            lastmodified = testfile.find('lastModified')    # get the lastmodified field in it's whole, so we can modify it.
            previous_update = datetime.strptime(lastmodified.text, '%Y-%m-%d %H:%M:%S') # get the previous date from the lastmodified field and translate it from the str format

            if previous_update < today:
                lastmodified.text = str(today.strftime('%Y-%m-%d %H:%M:%S'))
                self.getMetadataTree().write(self.meta_file)

But for some reason, the meta_file is not changing... What am I doing wrong???

The problem is after the if statement, where the file is not being modified

here are the other methods i'm using in this class:

def __init__(self, filepath):
        self.meta_file = filepath

def getMetadataTree(self):
    return ET.parse(self.meta_file)

def getMetadataRoot(self):        
    tree = self.getMetadataTree()
    root = tree.getroot()
    return root 

Upvotes: 0

Views: 2086

Answers (1)

Happy001
Happy001

Reputation: 6383

Your definition of self.getMetadataTree() re-parse the input file every time it gets called. So in the line self.getMetadataTree().write(self.meta_file), it parse the meta file and write it back (the same info). All previous modification to timestamp is not relevant (it's a different instance of ElementTree).

I guess you want to do something like this:

import xml.etree.ElementTree as ET
import sys
from datetime import datetime

class TimestampUpdater(object):

    def __init__(self, filepath):
        self.meta_file = filepath
        self.tree = ET.parse(self.meta_file)

    def getMetadataTree(self):
        return self.tree

    def getMetadataRoot(self):        
        return self.tree.getroot()

    def updateLastModified(self):
            today = datetime.now()
            for testfile in self.getMetadataRoot().findall('testfile'):
                lastmodified = testfile.find('lastModified')
                previous_update = datetime.strptime(lastmodified.text, '%Y-%m-%d %H:%M:%S')
                if previous_update < today:
                    lastmodified.text = today.strftime('%Y-%m-%d %H:%M:%S')
                    self.getMetadataTree().write(self.meta_file)

def print_file_content(filename):
    """Print contents of a file."""
    with open(filename, 'r') as fh:
        for line in fh:
            print line.rstrip()

if __name__ == '__main__':
    metafile = 'test.xml'
    print "\n====Before updating:===="
    print_file_content(metafile)
    updater = TimestampUpdater(metafile)
    updater.updateLastModified() 
    print "\n====After updating:===="
    print_file_content(metafile)

Output:

====Before updating:====
<project name="Hello World">
        <testfile name="testfile1">
                <type>TXT</type>
                <size>1000</size>
                <lastModified>2016-08-07 16:58:23</lastModified>
        </testfile>
        <testfile name="testfile2">
                <type>PDF</type>
                <size>500</size>
                <lastModified>2016-08-07 16:58:23</lastModified>
        </testfile>
</project>

====After updating:====
<project name="Hello World">
        <testfile name="testfile1">
                <type>TXT</type>
                <size>1000</size>
                <lastModified>2016-08-07 16:58:36</lastModified>
        </testfile>
        <testfile name="testfile2">
                <type>PDF</type>
                <size>500</size>
                <lastModified>2016-08-07 16:58:36</lastModified>
        </testfile>
</project>

Upvotes: 2

Related Questions