Replacing files in a zip archive
Дамјан Георгиевски
gdamjan at gmail.com
Thu Apr 30 19:37:18 EDT 2009
> 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.
More information about the Python-list
mailing list