> I'm writing a script that should modify ODF files. ODF files are just > .zip archives with some .xml files, images etc. > > So far I open the zip file and play with the xml with lxml.etree, but > I can't replace the files in it. > > Is there some recipe that does this ?
I ended writing this, pretty specific subclass of ZipFile. I've added 3 methods, one for getting the .xml content from the document, the other for setting (notifying) back the changes, and the third to save a copy of the ZipFile to another file (or in memory/StringIO). class ODFFile(ZipFile): def __init__(self, file, mode='r', compression=0, allowZip64=False): ZipFile.__init__(self, file, mode='r', compression=0, allowZip64=False) self.__unchanged = self.namelist() self.__updated = {} def get_xml(self, name): fp = self.open('%s.xml' % name) return lxml.etree.parse(fp) def set_xml(self, name, tree): name = '%s.xml' % name if name in self.__unchanged: self.__unchanged.remove(name) if tree is not None: self.__updated[name] = tree def save_changes(self, fp=None): if fp is None: fp = StringIO() zo = ZipFile(fp, mode='w') updated = dict(self.__updated) for zinfo in self.infolist(): name = zinfo.filename # just copy the unchanged if name in self.__unchanged: zo.writestr(zinfo, self.read(zinfo)) # write the changed in the same order elif name in updated: s = lxml.etree.tostring(updated.pop(name)) zo.writestr(name, s) # append the possible remaining (new?) for name, tree in updated.items(): s = lxml.etree.tostring(tree) zo.writestr(name, s) zo.close() return fp -- дамјан ( http://softver.org.mk/damjan/ ) Religion ends and philosophy begins, just as alchemy ends and chemistry begins and astrology ends, and astronomy begins. -- http://mail.python.org/mailman/listinfo/python-list