Log message for revision 109073: LP #195761: fixed ZMI XML export / import and restored it to the UI.
Changed: U Zope/branches/2.12/doc/CHANGES.rst U Zope/branches/2.12/src/OFS/XMLExportImport.py U Zope/branches/2.12/src/OFS/dtml/importExport.dtml A Zope/branches/2.12/src/OFS/tests/export.xml U Zope/branches/2.12/src/OFS/tests/test_XMLExportImport.py U Zope/branches/2.12/src/Shared/DC/xml/ppml.py -=- Modified: Zope/branches/2.12/doc/CHANGES.rst =================================================================== --- Zope/branches/2.12/doc/CHANGES.rst 2010-02-15 23:04:36 UTC (rev 109072) +++ Zope/branches/2.12/doc/CHANGES.rst 2010-02-15 23:05:42 UTC (rev 109073) @@ -20,6 +20,8 @@ Bugs Fixed ++++++++++ +- LP #195761: fixed ZMI XML export / import and restored it to the UI. + - MailHost should fall back to HELO when EHLO fails. Zope 2.12.3 (2010/01/12) Modified: Zope/branches/2.12/src/OFS/XMLExportImport.py =================================================================== --- Zope/branches/2.12/src/OFS/XMLExportImport.py 2010-02-15 23:04:36 UTC (rev 109072) +++ Zope/branches/2.12/src/OFS/XMLExportImport.py 2010-02-15 23:05:42 UTC (rev 109073) @@ -14,6 +14,8 @@ from cStringIO import StringIO from ZODB.serialize import referencesf from ZODB.ExportImport import TemporaryFile, export_end_marker +from ZODB.utils import p64 +from ZODB.utils import u64 from Shared.DC.xml import ppml @@ -23,7 +25,7 @@ q=ppml.ToXMLUnpickler f=StringIO(p) u=q(f) - id=ppml.u64(oid) + id=u64(oid) aka=encodestring(oid)[:-1] u.idprefix=str(id)+'.' p=u.load().__str__(4) @@ -93,11 +95,11 @@ file.seek(pos) a=data[1] if a.has_key('id'): oid=a['id'] - oid=ppml.p64(int(oid)) + oid=p64(int(oid)) v='' for x in data[2:]: v=v+x - l=ppml.p64(len(v)) + l=p64(len(v)) v=oid+l+v return v Modified: Zope/branches/2.12/src/OFS/dtml/importExport.dtml =================================================================== --- Zope/branches/2.12/src/OFS/dtml/importExport.dtml 2010-02-15 23:04:36 UTC (rev 109072) +++ Zope/branches/2.12/src/OFS/dtml/importExport.dtml 2010-02-15 23:05:42 UTC (rev 109073) @@ -10,16 +10,12 @@ to download the export file to your local machine, or save it in the "var" directory of your Zope installation on the server. -<!-- <br/> <br/> <b>Note:</b> -Zope can export/import objects in two dfferent formats: a binary format (called +Zope can export/import objects in two different formats: a binary format (called ZEXP) and as XML. The ZEXP format is the officially supported export/import format for moving data between <u>identical</u> Zope installations (it is not a migration tool). -The XML export/import is unsupported (and possibly broken under certain circumstances) - use it -at your own risk. ---> </p> <form action="manage_exportObject" method="post"> @@ -54,7 +50,6 @@ </div> </td> </tr> -<!-- <tr> <td align="left" valign="top"> @@ -69,7 +64,6 @@ </div> </td> </tr> ---> <tr> <td></td> <td align="left" valign="top"> Added: Zope/branches/2.12/src/OFS/tests/export.xml =================================================================== --- Zope/branches/2.12/src/OFS/tests/export.xml (rev 0) +++ Zope/branches/2.12/src/OFS/tests/export.xml 2010-02-15 23:05:42 UTC (rev 109073) @@ -0,0 +1,344 @@ +<?xml version="1.0"?> +<ZopeData> + <record id="482504664188191745" aka="BrIzb4doBAE="> + <pickle> + <tuple id="482504664188191745.2"> + <global id="482504664188191745.1" name="Folder" module="OFS.Folder"/> + <tuple/> + </tuple> + </pickle> + <pickle> + <dictionary id="482504664188191745.3"> + <item> + <key><string id="482504664188191745.4" encoding="">_objects</string></key> + <value> + <tuple id="482504664188191745.10"> + <dictionary id="482504664188191745.5"> + <item> + <key><string id="482504664188191745.6" encoding="">meta_type</string></key> + <value><string id="482504664188191745.7" encoding="">Image</string></value> + </item> + <item> + <key><string id="482504664188191745.8" encoding="">id</string></key> + <value><string id="482504664188191745.9" encoding="">image</string></value> + </item> + </dictionary> + </tuple> + </value> + </item> + <item> + <key><reference id="482504664188191745.9"/></key> + <value> + <persistent><string id="482504664188191745.11" encoding="base64">BrIzb4doBAI=</string></persistent> + </value> + </item> + <item> + <key><reference id="482504664188191745.8"/></key> + <value><string id="482504664188191745.12" encoding="">sub</string></value> + </item> + </dictionary> + </pickle> + </record> + <record id="482504664188191746" aka="BrIzb4doBAI="> + <pickle> + <tuple id="482504664188191746.2"> + <global id="482504664188191746.1" name="Image" module="OFS.Image"/> + <tuple/> + </tuple> + </pickle> + <pickle> + <dictionary id="482504664188191746.3"> + <item> + <key><string id="482504664188191746.4" encoding="">precondition</string></key> + <value><string encoding=""></string></value> + </item> + <item> + <key><string id="482504664188191746.5" encoding="">height</string></key> + <value><int>16</int></value> + </item> + <item> + <key><string id="482504664188191746.6" encoding="">size</string></key> + <value><int>894</int></value> + </item> + <item> + <key><string id="482504664188191746.7" encoding="">title</string></key> + <value><string encoding=""></string></value> + </item> + <item> + <key><string id="482504664188191746.8" encoding="">width</string></key> + <value><int>16</int></value> + </item> + <item> + <key><string id="482504664188191746.9" encoding="">_EtagSupport__etag</string></key> + <value><string id="482504664188191746.10" encoding="">ts65767150.22</string></value> + </item> + <item> + <key><string id="482504664188191746.11" encoding="">prop3</string></key> + <value><long>2147483647</long></value> + </item> + <item> + <key><string id="482504664188191746.12" encoding="">content_type</string></key> + <value><string id="482504664188191746.13" encoding="">image/gif</string></value> + </item> + <item> + <key><string id="482504664188191746.14" encoding="">__name__</string></key> + <value><string id="482504664188191746.15" encoding="">image</string></value> + </item> + <item> + <key><string id="482504664188191746.16" encoding="">data</string></key> + <value><string id="482504664188191746.17" encoding="base64">R0lGODlhEAAQAPcAAP8A/wAAAFBQUICAgMDAwP8AAIAAQAAAoABAgIAAgEAAQP//AP//gACAgECA +gP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAA +AAhbAAMIHEhwIICDAQ4qXIhQYUKFCCIufAiAYsSLDjMWiFjgoMSODkECAMmRIcWDBTYiYMjS40qT +DFWKRHmyY8mRKStmXJhzp04AEllSfBgUZsOWPk+2HFqwaYCAAAA7</string></value> + </item> + <item> + <key><string id="482504664188191746.18" encoding="">prop12</string></key> + <value><unicode encoding="">£</unicode></value> + </item> + <item> + <key><string id="482504664188191746.19" encoding="">prop10</string></key> + <value><string id="482504664188191746.20" encoding=""><]]></string></value> + </item> + <item> + <key><string id="482504664188191746.21" encoding="">prop11</string></key> + <value><unicode id="482504664188191746.22" encoding=""><]]></unicode></value> + </item> + <item> + <key><string id="482504664188191746.23" encoding="">prop4</string></key> + <value><string id="482504664188191746.24" encoding="">xxx</string></value> + </item> + <item> + <key><string id="482504664188191746.25" encoding="">prop5</string></key> + <value> + <tuple id="482504664188191746.27"> + <reference id="482504664188191746.24"/> + <string id="482504664188191746.26" encoding="">zzz</string> + </tuple> + </value> + </item> + <item> + <key><string id="482504664188191746.28" encoding="">prop6</string></key> + <value><unicode id="482504664188191746.29" encoding="">xxx</unicode></value> + </item> + <item> + <key><string id="482504664188191746.30" encoding="">prop7</string></key> + <value> + <tuple id="482504664188191746.32"> + <reference id="482504664188191746.29"/> + <unicode id="482504664188191746.31" encoding="">zzz</unicode> + </tuple> + </value> + </item> + <item> + <key><string id="482504664188191746.33" encoding="">prop1</string></key> + <value><float>3.14159265359</float></value> + </item> + <item> + <key><string id="482504664188191746.34" encoding="">prop2</string></key> + <value><int>1</int></value> + </item> + <item> + <key><string id="482504664188191746.35" encoding="">_properties</string></key> + <value> + <tuple id="482504664188191746.66"> + <dictionary id="482504664188191746.36"> + <item> + <key><string id="482504664188191746.37" encoding="">type</string></key> + <value><string id="482504664188191746.38" encoding="">string</string></value> + </item> + <item> + <key><string id="482504664188191746.39" encoding="">id</string></key> + <value><reference id="482504664188191746.7"/></value> + </item> + </dictionary> + <dictionary id="482504664188191746.40"> + <item> + <key><reference id="482504664188191746.37"/></key> + <value><reference id="482504664188191746.38"/></value> + </item> + <item> + <key><reference id="482504664188191746.39"/></key> + <value><string id="482504664188191746.41" encoding="">alt</string></value> + </item> + </dictionary> + <dictionary id="482504664188191746.42"> + <item> + <key><reference id="482504664188191746.37"/></key> + <value><reference id="482504664188191746.38"/></value> + </item> + <item> + <key><reference id="482504664188191746.39"/></key> + <value><reference id="482504664188191746.12"/></value> + </item> + <item> + <key><string id="482504664188191746.43" encoding="">mode</string></key> + <value><string encoding="">w</string></value> + </item> + </dictionary> + <dictionary id="482504664188191746.44"> + <item> + <key><reference id="482504664188191746.37"/></key> + <value><reference id="482504664188191746.38"/></value> + </item> + <item> + <key><reference id="482504664188191746.39"/></key> + <value><reference id="482504664188191746.5"/></value> + </item> + </dictionary> + <dictionary id="482504664188191746.45"> + <item> + <key><reference id="482504664188191746.37"/></key> + <value><reference id="482504664188191746.38"/></value> + </item> + <item> + <key><reference id="482504664188191746.39"/></key> + <value><reference id="482504664188191746.8"/></value> + </item> + </dictionary> + <dictionary id="482504664188191746.46"> + <item> + <key><reference id="482504664188191746.37"/></key> + <value><string id="482504664188191746.47" encoding="">float</string></value> + </item> + <item> + <key><reference id="482504664188191746.39"/></key> + <value><reference id="482504664188191746.33"/></value> + </item> + </dictionary> + <dictionary id="482504664188191746.48"> + <item> + <key><reference id="482504664188191746.37"/></key> + <value><string id="482504664188191746.49" encoding="">int</string></value> + </item> + <item> + <key><reference id="482504664188191746.39"/></key> + <value><reference id="482504664188191746.34"/></value> + </item> + </dictionary> + <dictionary id="482504664188191746.50"> + <item> + <key><reference id="482504664188191746.37"/></key> + <value><string id="482504664188191746.51" encoding="">long</string></value> + </item> + <item> + <key><reference id="482504664188191746.39"/></key> + <value><reference id="482504664188191746.11"/></value> + </item> + </dictionary> + <dictionary id="482504664188191746.52"> + <item> + <key><reference id="482504664188191746.37"/></key> + <value><reference id="482504664188191746.38"/></value> + </item> + <item> + <key><reference id="482504664188191746.39"/></key> + <value><reference id="482504664188191746.23"/></value> + </item> + </dictionary> + <dictionary id="482504664188191746.53"> + <item> + <key><reference id="482504664188191746.37"/></key> + <value><string id="482504664188191746.54" encoding="">lines</string></value> + </item> + <item> + <key><reference id="482504664188191746.39"/></key> + <value><reference id="482504664188191746.25"/></value> + </item> + </dictionary> + <dictionary id="482504664188191746.55"> + <item> + <key><reference id="482504664188191746.37"/></key> + <value><string id="482504664188191746.56" encoding="">unicode</string></value> + </item> + <item> + <key><reference id="482504664188191746.39"/></key> + <value><reference id="482504664188191746.28"/></value> + </item> + </dictionary> + <dictionary id="482504664188191746.57"> + <item> + <key><reference id="482504664188191746.37"/></key> + <value><string id="482504664188191746.58" encoding="">ulines</string></value> + </item> + <item> + <key><reference id="482504664188191746.39"/></key> + <value><reference id="482504664188191746.30"/></value> + </item> + </dictionary> + <dictionary id="482504664188191746.59"> + <item> + <key><reference id="482504664188191746.37"/></key> + <value><reference id="482504664188191746.38"/></value> + </item> + <item> + <key><reference id="482504664188191746.39"/></key> + <value><string id="482504664188191746.60" encoding="">prop8</string></value> + </item> + </dictionary> + <dictionary id="482504664188191746.61"> + <item> + <key><reference id="482504664188191746.37"/></key> + <value><reference id="482504664188191746.56"/></value> + </item> + <item> + <key><reference id="482504664188191746.39"/></key> + <value><string id="482504664188191746.62" encoding="">prop9</string></value> + </item> + </dictionary> + <dictionary id="482504664188191746.63"> + <item> + <key><reference id="482504664188191746.37"/></key> + <value><reference id="482504664188191746.38"/></value> + </item> + <item> + <key><reference id="482504664188191746.39"/></key> + <value><reference id="482504664188191746.19"/></value> + </item> + </dictionary> + <dictionary id="482504664188191746.64"> + <item> + <key><reference id="482504664188191746.37"/></key> + <value><reference id="482504664188191746.56"/></value> + </item> + <item> + <key><reference id="482504664188191746.39"/></key> + <value><reference id="482504664188191746.21"/></value> + </item> + </dictionary> + <dictionary id="482504664188191746.65"> + <item> + <key><reference id="482504664188191746.37"/></key> + <value><reference id="482504664188191746.56"/></value> + </item> + <item> + <key><reference id="482504664188191746.39"/></key> + <value><reference id="482504664188191746.18"/></value> + </item> + </dictionary> + </tuple> + </value> + </item> + <item> + <key><reference id="482504664188191746.60"/></key> + <value><string id="482504664188191746.67" encoding="cdata"><![CDATA[<&>]]></string></value> + </item> + <item> + <key><reference id="482504664188191746.62"/></key> + <value><unicode id="482504664188191746.68" encoding="cdata"><![CDATA[<&>]]></unicode></value> + </item> + </dictionary> + </pickle> + </record> +</ZopeData> Modified: Zope/branches/2.12/src/OFS/tests/test_XMLExportImport.py =================================================================== --- Zope/branches/2.12/src/OFS/tests/test_XMLExportImport.py 2010-02-15 23:04:36 UTC (rev 109072) +++ Zope/branches/2.12/src/OFS/tests/test_XMLExportImport.py 2010-02-15 23:05:42 UTC (rev 109073) @@ -1,3 +1,4 @@ +# -*- coding: iso8859-1 -*- ############################################################################## # # Copyright (c) 2006 Zope Corporation and Contributors. All Rights Reserved. @@ -16,8 +17,16 @@ import transaction from StringIO import StringIO -_LONG_DTML = '\n'.join([('<dtml-var foo%d' % x) for x in xrange(1000)]) +try: + here = os.path.dirname(os.path.abspath(__file__)) +except: + here = os.path.dirname(os.path.abspath(sys.argv[0])) +imagedata = os.path.join(here, 'test.gif') +xmldata = os.path.join(here, 'export.xml') + +_LONG_DTML = ''.join([('<dtml-var foo%d' % x) for x in xrange(1000)]) + class XMLExportImportTests(unittest.TestCase): def _makeJarAndRoot(self): @@ -112,6 +121,75 @@ # the block above. os.remove(path) + def test_exportXML(self): + from OFS.Folder import Folder + from OFS.Image import Image + from OFS.XMLExportImport import exportXML + + connection, app = self._makeJarAndRoot() + data = open(imagedata, 'rb') + + sub = Folder('sub') + app._setObject('sub', sub) + img = Image('image', '', data, 'image/gif') + sub._setObject('image', img) + img._setProperty('prop1', 3.14159265359, 'float') + img._setProperty('prop2', 1, 'int') + img._setProperty('prop3', 2L**31-1, 'long') + img._setProperty('prop4', 'xxx', 'string') + img._setProperty('prop5', ['xxx', 'zzz'], 'lines') + img._setProperty('prop6', u'xxx', 'unicode') + img._setProperty('prop7', [u'xxx', u'zzz'], 'ulines') + img._setProperty('prop8', '<&>', 'string') + img._setProperty('prop9', u'<&>', 'unicode') + img._setProperty('prop10', '<]]>', 'string') + img._setProperty('prop11', u'<]]>', 'unicode') + img._setProperty('prop12', u'£', 'unicode') + transaction.savepoint(optimistic=True) + oid = sub._p_oid + + handle, path = tempfile.mkstemp(suffix='.xml') + try: + ostream = os.fdopen(handle,'wb') + data = exportXML(connection, oid, ostream) + ostream.close() + finally: + os.remove(path) + + def test_importXML(self): + from OFS.XMLExportImport import importXML + + connection, app = self._makeJarAndRoot() + newobj = importXML(connection, xmldata) + img = newobj._getOb('image') + data = open(imagedata, 'rb').read() + + self.assertEqual(img.data, data) + self.assertEqual(repr(img.getProperty('prop1')), + repr(3.14159265359)) + self.assertEqual(repr(img.getProperty('prop2')), + repr(1)) + self.assertEqual(repr(img.getProperty('prop3')), + repr(2L**31-1)) + self.assertEqual(repr(img.getProperty('prop4')), + repr('xxx')) + self.assertEqual(repr(img.getProperty('prop5')), + repr(('xxx', 'zzz'))) + self.assertEqual(repr(img.getProperty('prop6')), + repr(u'xxx')) + self.assertEqual(repr(img.getProperty('prop7')), + repr((u'xxx', u'zzz'))) + self.assertEqual(repr(img.getProperty('prop8')), + repr('<&>')) + self.assertEqual(repr(img.getProperty('prop9')), + repr(u'<&>')) + self.assertEqual(repr(img.getProperty('prop10')), + repr('<]]>')) + self.assertEqual(repr(img.getProperty('prop11')), + repr(u'<]]>')) + self.assertEqual(repr(img.getProperty('prop12')), + repr(u'£')) + def test_suite(): return unittest.TestSuite(( unittest.makeSuite(XMLExportImportTests), Modified: Zope/branches/2.12/src/Shared/DC/xml/ppml.py =================================================================== --- Zope/branches/2.12/src/Shared/DC/xml/ppml.py 2010-02-15 23:04:36 UTC (rev 109072) +++ Zope/branches/2.12/src/Shared/DC/xml/ppml.py 2010-02-15 23:05:42 UTC (rev 109073) @@ -17,119 +17,68 @@ __version__ = "1.9" # Code version from pickle import * -from string import replace import struct import base64 -import string -import pickle -import tempfile -import marshal -import xyap +import re +from marshal import loads as mloads +from xyap import NoBlanks +from xyap import xyap -mdumps = marshal.dumps -mloads = marshal.loads +binary = re.compile('[^\x1f-\x7f]').search -xyap=xyap.xyap -ListType=type([]) - -# Create repr mappong -reprs = {} -for c in map(chr,range(256)): reprs[c] = repr(c)[1:-1] -reprs['\n'] = "\\n\n" -reprs['\t'] = "\\t" -reprs['\\'] = "\\\\" -reprs['\r'] = "\\r" -reprs["'"] = "\\'" -reprs2={} -reprs2['<'] = "\\074" -reprs2['>'] = "\\076" -reprs2['&'] = "\\046" - - -# Function convert takes a string and converts it to either -# repr or base64 format - -def convert(S, find=string.find): - new = '' - encoding = 'repr' - new = string.join(map(reprs.get, S), '') - if len(new) > (1.4*len(S)): +def escape(s, encoding='repr'): + if binary(s) and isinstance(s, str): + s = base64.encodestring(s)[:-1] encoding = 'base64' - new = base64.encodestring(S)[:-1] - elif find(new,'>') >= 0 or find(new,'<') >= 0 or find(new,'&') >= 0: - if find(new, ']]>') <0 : - new='<![CDATA[\n\n'+new+'\n\n]]>' - encoding='cdata' + elif '>' in s or '<' in s or '&' in s: + if not ']]>' in s: + s = '<![CDATA[' + s + ']]>' + encoding = 'cdata' else: - new=string.join(map(lambda s: reprs2.get(s,s), new), '') - return encoding, new + s = s.replace('&', '&') + s = s.replace('>', '>') + s = s.replace('<', '<') + return encoding, s -# Function unconvert takes a encoding and a string and -# returns the original string - -def unconvert(encoding,S): - original = '' +def unescape(s, encoding): if encoding == 'base64': - original = base64.decodestring(S) + return base64.decodestring(s) else: - x = string.replace(S, '\n', '') - original = eval("'"+x+"'") - return original + s = s.replace('<', '<') + s = s.replace('>', '>') + return s.replace('&', '&') -t32 = 1L << 32 - -def p64(v, pack=struct.pack): - if v < t32: h=0 - else: - h=v/t32 - v=v%t32 - return pack(">II", h, v) - -def u64(v, unpack=struct.unpack): - h, v = unpack(">ii", v) - if v < 0: v=t32+v - if h: - if h < 0: h=t32+h - v=h*t32+v - return v - class Global: - def __init__(self, module, name): - self.module=module - self.name=name + self.module = module + self.name = name def __str__(self, indent=0): - if hasattr(self, 'id'): id=' id="%s"' % self.id - else: id='' - name=string.lower(self.__class__.__name__) + if hasattr(self, 'id'): + id = ' id="%s"' % self.id + else: + id = '' + name = self.__class__.__name__.lower() return '%s<%s%s name="%s" module="%s"/>\n' % ( - ' '*indent, name, id, self.name, self.module) + ' ' * indent, name, id, self.name, self.module) class Scalar: - def __init__(self, v): - self._v=v + self._v = v - def value(self): return self._v + def value(self): + return self._v def __str__(self, indent=0): - if hasattr(self, 'id'): id=' id="%s"' % self.id - else: id='' - name=string.lower(self.__class__.__name__) + if hasattr(self, 'id'): + id = ' id="%s"' % self.id + else: + id = '' + name = self.__class__.__name__.lower() return '%s<%s%s>%s</%s>\n' % ( - ' '*indent, name, id, self.value(), name) + ' ' * indent, name, id, self.value(), name) -def xmlstr(v): - v=`v` - if v[:1]=='\'': - v=string.replace(v,'"','\\"') - v=replace(v,'%','\\045') - v=replace(v,'&','\\046') - return v[1:-1] - -class Int(Scalar): pass class Long(Scalar): def value(self): result = str(self._v) @@ -137,65 +86,84 @@ return result[:-1] return result -class Float(Scalar): pass class String(Scalar): def __init__(self, v, encoding=''): - encoding, v = convert(v) - self.encoding=encoding - self._v=v - def __str__(self,indent=0): - if hasattr(self,'id'):id=' id="%s"' % self.id - else: id='' - if hasattr(self, 'encoding'):encoding=' encoding="%s"' % self.encoding - else: encoding='' - name=string.lower(self.__class__.__name__) + encoding, v = escape(v, encoding) + self.encoding = encoding + self._v = v + + def __str__(self, indent=0): + if hasattr(self,'id'): + id = ' id="%s"' % self.id + else: + id = '' + if hasattr(self, 'encoding'): + encoding = ' encoding="%s"' % self.encoding + else: + encoding = '' + name = self.__class__.__name__.lower() return '%s<%s%s%s>%s</%s>\n' % ( - ' '*indent, name, id, encoding, self.value(), name) + ' ' * indent, name, id, encoding, self.value(), name) -class Wrapper: +class Unicode(String): + def __init__(self, v, encoding): + v = unicode(v, encoding) + String.__init__(self, v) - def __init__(self, v): self._v=v + def value(self): + return self._v.encode('utf-8') - def value(self): return self._v +class Wrapper: + def __init__(self, v): + self._v = v + def value(self): + return self._v + def __str__(self, indent=0): - if hasattr(self, 'id'): id=' id="%s"' % self.id - else: id='' - name=string.lower(self.__class__.__name__) - v=self._v - i=' '*indent - if isinstance(v,Scalar): - return '%s<%s%s> %s </%s>\n' % (i, name, id, str(v)[:-1], name) + if hasattr(self, 'id'): + id = ' id="%s"' % self.id else: + id = '' + name = self.__class__.__name__.lower() + v = self._v + i = ' ' * indent + if isinstance(v, Scalar): + return '%s<%s%s>%s</%s>\n' % (i, name, id, str(v)[:-1], name) + else: try: - v=v.__str__(indent+2) + v = v.__str__(indent + 2) except TypeError: - v=v.__str__() + v = v.__str__() return '%s<%s%s>\n%s%s</%s>\n' % (i, name, id, v, i, name) class Collection: - def __str__(self, indent=0): - if hasattr(self, 'id'): id=' id="%s"' % self.id - else: id='' - name=string.lower(self.__class__.__name__) - i=' '*indent + if hasattr(self, 'id'): + id = ' id="%s"' % self.id + else: + id = '' + name = self.__class__.__name__.lower() + i = ' ' * indent if self: return '%s<%s%s>\n%s%s</%s>\n' % ( - i, name, id, self.value(indent+2), i, name) + i, name, id, self.value(indent + 2), i, name) else: return '%s<%s%s/>\n' % (i, name, id) -class Key(Wrapper): pass -class Value(Wrapper): pass - class Dictionary(Collection): - def __init__(self): self._d=[] - def __len__(self): return len(self._d) - def __setitem__(self, k, v): self._d.append((k,v)) + def __init__(self): + self._d = [] + + def __len__(self): + return len(self._d) + + def __setitem__(self, k, v): + self._d.append((k, v)) + def value(self, indent): - return string.join( - map(lambda i, ind=' '*indent, indent=indent+4: + return ''.join( + map(lambda i, ind=' ' * indent, indent=indent + 4: '%s<item>\n' '%s' '%s' @@ -206,62 +174,73 @@ Value(i[1]).__str__(indent), ind), self._d - ), - '') + )) class Sequence(Collection): - def __init__(self, v=None): - if not v: v=[] - self._subs=v + if not v: + v = [] + self._subs = v - def __len__(self): return len(self._subs) + def __len__(self): + return len(self._subs) - def append(self, v): self._subs.append(v) - def extend(self, v): self._subs.extend(v) + def append(self, v): + self._subs.append(v) + def extend(self, v): + self._subs.extend(v) + def _stringify(self, v, indent): try: - return v.__str__(indent+2) + return v.__str__(indent + 2) except TypeError: return v.__str__() def value(self, indent): - return string.join(map( + return ''.join(map( lambda v, indent=indent: self._stringify(v, indent), - self._subs),'') + self._subs)) -class List(Sequence): pass -class Tuple(Sequence): pass - -class Klass(Wrapper): pass -class State(Wrapper): pass -class Pickle(Wrapper): pass -class Persistent(Wrapper): pass - class none: - def __str__(self, indent=0): return ' '*indent+'<none/>\n' -none=none() + def __str__(self, indent=0): + return ' ' * indent + '<none/>\n' +none = none() class Reference(Scalar): - def __init__(self, v): self._v=v + def __init__(self, v): + self._v = v + def __str__(self, indent=0): - v=self._v - name=string.lower(self.__class__.__name__) - return '%s<%s id="%s"/>\n' % (' '*indent,name,v) + v = self._v + name = self.__class__.__name__.lower() + return '%s<%s id="%s"/>\n' % (' ' * indent, name, v) -Get=Reference +Get = Reference class Object(Sequence): def __init__(self, klass, args): - self._subs=[Klass(klass), args] + self._subs = [Klass(klass), args] - def __setstate__(self, v): self.append(State(v)) + def __setstate__(self, v): + self.append(State(v)) -class ToXMLUnpickler(Unpickler): +class Int(Scalar): pass +class Float(Scalar): pass +class List(Sequence): pass +class Tuple(Sequence): pass +class Key(Wrapper): pass +class Value(Wrapper): pass +class Klass(Wrapper): pass +class State(Wrapper): pass +class Pickle(Wrapper): pass +class Persistent(Wrapper): pass - def load(self): return Pickle(Unpickler.load(self)) +class ToXMLUnpickler(Unpickler): + def load(self): + return Pickle(Unpickler.load(self)) + dispatch = {} dispatch.update(Unpickler.dispatch) @@ -278,7 +257,7 @@ dispatch[NONE] = load_none def load_int(self): - self.append(Int(string.atoi(self.readline()[:-1]))) + self.append(Int(int(self.readline()[:-1]))) dispatch[INT] = load_int def load_binint(self): @@ -286,7 +265,7 @@ dispatch[BININT] = load_binint def load_binint1(self): - self.append(Int(mloads('i' + self.read(1) + '\000\000\000'))) + self.append(Int(ord(self.read(1)))) dispatch[BININT1] = load_binint1 def load_binint2(self): @@ -294,11 +273,11 @@ dispatch[BININT2] = load_binint2 def load_long(self): - self.append(Long(string.atol(self.readline()[:-1], 0))) + self.append(Long(long(self.readline()[:-1], 0))) dispatch[LONG] = load_long def load_float(self): - self.append(Float(string.atof(self.readline()[:-1]))) + self.append(Float(float(self.readline()[:-1]))) dispatch[FLOAT] = load_float def load_binfloat(self, unpack=struct.unpack): @@ -306,8 +285,16 @@ dispatch[BINFLOAT] = load_binfloat def load_string(self): - self.append(String(eval(self.readline()[:-1], - {'__builtins__': {}}))) # Let's be careful + rep = self.readline()[:-1] + for q in "\"'": + if rep.startswith(q): + if not rep.endswith(q): + raise ValueError, 'insecure string pickle' + rep = rep[len(q):-len(q)] + break + else: + raise ValueError, 'insecure string pickle' + self.append(String(rep.decode('string-escape'))) dispatch[STRING] = load_string def load_binstring(self): @@ -315,14 +302,23 @@ self.append(String(self.read(len))) dispatch[BINSTRING] = load_binstring + def load_unicode(self): + self.append(Unicode(self.readline()[:-1],'raw-unicode-escape')) + dispatch[UNICODE] = load_unicode + + def load_binunicode(self): + len = mloads('i' + self.read(4)) + self.append(Unicode(self.read(len),'utf-8')) + dispatch[BINUNICODE] = load_binunicode + def load_short_binstring(self): - len = mloads('i' + self.read(1) + '\000\000\000') + len = ord(self.read(1)) self.append(String(self.read(len))) dispatch[SHORT_BINSTRING] = load_short_binstring def load_tuple(self): k = self.marker() - self.stack[k:] = [Tuple(self.stack[k+1:])] + self.stack[k:] = [Tuple(self.stack[k + 1:])] dispatch[TUPLE] = load_tuple def load_empty_tuple(self): @@ -339,27 +335,27 @@ def load_list(self): k = self.marker() - self.stack[k:] = [List(self.stack[k+1:])] + self.stack[k:] = [List(self.stack[k + 1:])] dispatch[LIST] = load_list def load_dict(self): k = self.marker() d = Dictionary() - items = self.stack[k+1:] + items = self.stack[k + 1:] for i in range(0, len(items), 2): key = items[i] - value = items[i+1] + value = items[i + 1] d[key] = value self.stack[k:] = [d] dispatch[DICT] = load_dict def load_inst(self): k = self.marker() - args = Tuple(self.stack[k+1:]) + args = Tuple(self.stack[k + 1:]) del self.stack[k:] module = self.readline()[:-1] name = self.readline()[:-1] - value=Object(Global(module, name), args) + value = Object(Global(module, name), args) self.append(value) dispatch[INST] = load_inst @@ -370,7 +366,7 @@ del stack[k + 1] args = Tuple(stack[k + 1:]) del stack[k:] - value=Object(klass,args) + value = Object(klass, args) self.append(value) dispatch[OBJ] = load_obj @@ -384,45 +380,45 @@ stack = self.stack callable = stack[-2] - arg_tup = stack[-1] + arg_tup = stack[-1] del stack[-2:] - value=Object(callable, arg_tup) + value = Object(callable, arg_tup) self.append(value) dispatch[REDUCE] = load_reduce idprefix='' def load_get(self): - self.append(Get(self.idprefix+self.readline()[:-1])) + self.append(Get(self.idprefix + self.readline()[:-1])) dispatch[GET] = load_get def load_binget(self): - i = mloads('i' + self.read(1) + '\000\000\000') - self.append(Get(self.idprefix+`i`)) + i = ord(self.read(1)) + self.append(Get(self.idprefix + repr(i))) dispatch[BINGET] = load_binget def load_long_binget(self): i = mloads('i' + self.read(4)) - self.append(Get(self.idprefix+`i`)) + self.append(Get(self.idprefix + repr(i))) dispatch[LONG_BINGET] = load_long_binget def load_put(self): - self.stack[-1].id=self.idprefix+self.readline()[:-1] + self.stack[-1].id = self.idprefix + self.readline()[:-1] dispatch[PUT] = load_put def load_binput(self): - i = mloads('i' + self.read(1) + '\000\000\000') + i = ord(self.read(1)) last = self.stack[-1] if getattr(last, 'id', last) is last: - last.id = self.idprefix + `i` + last.id = self.idprefix + repr(i) dispatch[BINPUT] = load_binput def load_long_binput(self): i = mloads('i' + self.read(4)) last = self.stack[-1] if getattr(last, 'id', last) is last: - last.id = self.idprefix + `i` + last.id = self.idprefix + repr(i) dispatch[LONG_BINPUT] = load_long_binput @@ -430,230 +426,169 @@ return ToXMLUnpickler(file).load() def ToXMLloads(str): + from StringIO import StringIO file = StringIO(str) return ToXMLUnpickler(file).load() +def name(self, tag, data): + return ''.join(data[2:]).strip() - -class NoBlanks: - - def handle_data(self, data): - if string.strip(data): self.append(data) - -def name(self, tag, data, join=string.join, strip=string.strip): - return strip(join(data[2:],'')) - def start_pickle(self, tag, attrs): - self._pickleids={} - return [tag,attrs] + self._pickleids = {} + return [tag, attrs] -def end_string(self, tag, data): - v=data[2] - a=data[1] - if a['encoding'] is not '': - v=unconvert(a['encoding'],v) - if a.has_key('id'): self._pickleids[a['id']]=v - return v - -def end_list(self, tag, data): - v=data[2:] - a=data[1] - if a.has_key('id'): self._pickleids[data[1]['id']]=v - return v - -def end_tuple(self, tag, data): - v=tuple(data[2:]) - a=data[1] - if a.has_key('id'): self._pickleids[data[1]['id']]=v - return v - -def end_dictionary(self, tag, data): - D={} - a=data[1] - for k, v in data[2:]: D[k]=v - if a.has_key('id'): self._pickleids[a['id']]=D - return D - -class xmlUnpickler(NoBlanks, xyap): - start_handlers={'pickle': start_pickle} - end_handlers={ - 'int': - lambda self,tag,data,atoi=string.atoi,name=name: - atoi(name(self, tag, data)), - 'long': - lambda self,tag,data,atoi=string.atoi,name=name: - atoi(name(self, tag, data)), - 'boolean': - lambda self,tag,data,atoi=string.atoi,name=name: - atoi(name(self, tag, data)), - 'string': end_string , - 'double': - lambda self,tag,data,atof=string.atof,name=name: - atof(name(self, tag, data)), - 'float': - lambda self,tag,data,atof=string.atof,name=name: - atof(name(self, tag, data)), - 'none': lambda self, tag, data: None, - 'list': end_list, - 'tuple': end_tuple, - 'dictionary': end_dictionary, - 'key': lambda self, tag, data: data[2], - 'value': lambda self, tag, data: data[2], - 'item': lambda self, tag, data: data[2:], - 'reference': lambda self, tag, data: self._pickleids[data[1]['id']], - 'state': lambda self, tag, data: data[2], - 'klass': lambda self, tag, data: data[2], - } - def save_int(self, tag, data): - binary=self.binary - if binary: - v=string.atoi(name(self, tag, data)) - i=mdumps(v)[1:] - if (i[-2:] == '\000\000'): - if (i[-3] == '\000'): - v='K'+i[:-3] - return v - v='M'+i[:-2] - return v - v='J'+i - return v - v='I'+name(self, tag, data)+'\012' - return v + if self.binary: + v = int(name(self, tag, data)) + if v >= 0: + if v <= 0xff: + return BININT1 + chr(v) + if v <= 0xffff: + return '%c%c%c' % (BININT2, v & 0xff, v >> 8) + hb = v >> 31 + if hb == 0 or hb == -1: + return BININT + struct.pack('<i', v) + return INT + name(self, tag, data) + '\n' def save_float(self, tag, data): - binary=self.binary - if binary: v='G'+struct.pack('>d',string.atof(name(self, tag, data))) - else: v='F'+name(self, tag, data)+'\012' - return v + if self.binary: + return BINFLOAT + struct.pack('>d', float(name(self, tag, data))) + else: + return FLOAT + name(self, tag, data) + '\n' def save_put(self, v, attrs): - id=attrs.get('id','') + id = attrs.get('id', '') if id: - prefix=string.rfind(id,'.') - if prefix >= 0: id=id[prefix+1:] - elif id[0]=='i': id=id[1:] + prefix = id.rfind('.') + if prefix >= 0: + id = id[prefix + 1:] + elif id[0] == 'i': + id = id[1:] if self.binary: - id=string.atoi(id) - s=mdumps(id)[1:] - if (id < 256): - id=s[0] - put='q' + id = int(id) + if id < 256: + id = BINPUT + chr(id) else: - id=s - put='r' - id=put+id + id = LONG_BINPUT + struct.pack('<i', id) else: - id="p"+id+"\012" - return v+id + id = PUT + repr(id) + '\n' + return v + id return v def save_string(self, tag, data): - binary=self.binary - v='' - a=data[1] - if len(data)>2: - for x in data[2:]: - v=v+x - encoding=a['encoding'] + a = data[1] + v = ''.join(data[2:]) + encoding = a['encoding'] if encoding is not '': - v=unconvert(encoding,v) - put='p' - if binary: - l=len(v) - s=mdumps(l)[1:] - if (l<256): - v='U'+s[0]+v + v = unescape(v, encoding) + if self.binary: + l = len(v) + if l < 256: + v = SHORT_BINSTRING + chr(l) + v else: - v='T'+s+v - put='q' - else: v="S'"+v+"'\012" + v = BINSTRING + struct.pack('<i', l) + v + else: + v = STRING + repr(v) + '\n' return save_put(self, v, a) +def save_unicode(self, tag, data): + a = data[1] + v = ''.join(data[2:]) + encoding = a['encoding'] + if encoding is not '': + v = unescape(v, encoding) + if self.binary: + v = v.encode('utf-8') + v = BINUNICODE + struct.pack("<i", len(v)) + v + else: + v = v.replace("\\", "\\u005c") + v = v.replace("\n", "\\u000a") + v.encode('raw-unicode-escape') + v = UNICODE + v + '\n' + return save_put(self, v, a) + def save_tuple(self, tag, data): - T=data[2:] - if not T: return ')' - return save_put(self, '('+string.join(T,'')+'t', data[1]) + T = data[2:] + if not T: + return EMPTY_TUPLE + return save_put(self, MARK + ''.join(T) + TUPLE, data[1]) def save_list(self, tag, data): - L=data[2:] - a=data[1] + L = data[2:] if self.binary: - v=save_put(self, ']', a) - if L: v=v+'('+string.join(L,'')+'e' + v = save_put(self, EMPTY_LIST, data[1]) + if L: + v = v + MARK + ''.join(L) + APPENDS else: - v=save_put(self, '(l', a) - if L: v=string.join(L,'a')+'a' + v = save_put(self, MARK + LIST, data[1]) + if L: + v = APPEND.join(L) + APPEND return v def save_dict(self, tag, data): - D=data[2:] + D = data[2:] if self.binary: - v=save_put(self, '}', data[1]) - if D: v=v+'('+string.join(D,'')+'u' + v = save_put(self, EMPTY_DICT, data[1]) + if D: + v = v + MARK + ''.join(D) + SETITEMS else: - v=save_put(self, '(d', data[1]) - if D: v=v+string.join(D,'s')+'s' + v = save_put(self, MARK + DICT, data[1]) + if D: + v = v + SETITEM.join(D) + SETITEM return v def save_reference(self, tag, data): - binary=self.binary - a=data[1] - id=a['id'] - prefix=string.rfind(id,'.') - if prefix>=0: id=id[prefix+1:] - get='g' - if binary: - id=string.atoi(id) - s=mdumps(id)[1:] - if (id < 256): - id=s[0] - get='h' + a = data[1] + id = a['id'] + prefix = id.rfind('.') + if prefix >= 0: + id = id[prefix + 1:] + if self.binary: + id = int(id) + if id < 256: + return BINGET + chr(id) else: - id=s - get='j' - v=get+id - else: v=get+id+'\012' + return LONG_BINGET + struct.pack('<i', i) + else: + return GET + repr(id) + '\n' - return v - def save_object(self, tag, data): - v='('+data[2] - x=data[3][1:] - stop=string.rfind(x,'t') # This seems - if stop>=0: x=x[:stop] # wrong! - v=save_put(self, v+x+'o', data[1]) - v=v+data[4]+'b' # state + v = MARK + data[2] + x = data[3][1:] + stop = x.rfind('t') # This seems + if stop >= 0: # wrong! + x = x[:stop] + v = save_put(self, v + x + OBJ, data[1]) + v = v + data[4] + BUILD # state return v def save_global(self, tag, data): - a=data[1] - return save_put(self, 'c'+a['module']+'\012'+a['name']+'\012', a) + a = data[1] + return save_put(self, GLOBAL + a['module'] + '\n' + a['name'] + '\n', a) def save_persis(self, tag, data): - v=data[2] - if self.binary: - v=v+'Q' + v = data[2] + if self.binary: + return v + BINPERSID else: - v='P'+v - return v + return PERSID + v class xmlPickler(NoBlanks, xyap): - start_handlers={ + start_handlers = { 'pickle': lambda self, tag, attrs: [tag, attrs], } - end_handlers={ - 'pickle': lambda self, tag, data: str(data[2])+'.', - 'none': lambda self, tag, data: 'N', + end_handlers = { + 'pickle': lambda self, tag, data: str(data[2]) + STOP, + 'none': lambda self, tag, data: NONE, 'int': save_int, - 'long': lambda self, tag, data: 'L'+str(data[2])+'L\012', + 'long': lambda self, tag, data: LONG + str(data[2]) + LONG + '\n', 'float': save_float, 'string': save_string, 'reference': save_reference, 'tuple': save_tuple, 'list': save_list, 'dictionary': save_dict, - 'item': lambda self, tag, data, j=string.join: j(data[2:],''), + 'item': lambda self, tag, data: ''.join(map(str, data[2:])), 'value': lambda self, tag, data: data[2], 'key' : lambda self, tag, data: data[2], 'object': save_object, @@ -661,6 +596,7 @@ 'state': lambda self, tag, data: data[2], 'global': save_global, 'persistent': save_persis, + 'unicode': save_unicode, } @@ -672,16 +608,17 @@ def test(): import xmllib - c=C() - c.foo=1 - c.bar=2 - x=[0,1,2,3] - y=('abc','abc',c,c) + import pickle + c = C() + c.foo = 1 + c.bar = 2 + x = [0, 1, 2, 3] + y = ('abc', 'abc', c, c) x.append(y) x.append(y) - t=() - l=[] - s='' + t = () + l = [] + s = '' L = long('999999999999') x.append(t) x.append(l) @@ -689,78 +626,52 @@ x.append(L) x.append(55555) x.append(13) - r=[x] + r = [x] print x - f=pickle.dumps(x) + f = pickle.dumps(x) print f r.append(f) - q=ToXMLloads(f) - q=str(q) - q='<?xml version="1.0"?>\n'+q + q = ToXMLloads(f) + q = str(q) + q = '<?xml version="1.0"?>\n' + q print q r.append(q) - file='' - F=xmlPickler(file) - p=xmllib.XMLParser() - p.start_handlers=F.start_handlers - p.end_handlers=F.end_handlers - p.handle_data=F.handle_data - p.unknown_starttag=F.unknown_starttag - p.unknown_endtag=F.unknown_endtag - p._stack=F._stack - p.push=F.push - p.append=F.append - p.file=F.file - p.tempfile=F.tempfile - p.binary=1 - data=string.split(q,'\n') + F = xmlPickler() + F.binary = 1 + p = xmllib.XMLParser() + p.start_handlers = F.start_handlers + p.end_handlers = F.end_handlers + p.handle_data = F.handle_data + p.unknown_starttag = F.unknown_starttag + p.unknown_endtag = F.unknown_endtag + p._stack = F._stack + p.push = F.push + p.append = F.append + data = q.split('\n') for l in data: p.feed(l) p.close() - z=p._stack - z=z[0][0] - print z, '\012' + z = p._stack + z = z[0][0] + print z, '\n' r.append(z) - l=pickle.loads(z) - print l, '\012' + l = pickle.loads(z) + print l, '\n' r.append(l) def test1(): - import xmllib - q=open('Data.xml').read() - file=open('out','w'+'b') - F=xmlPickler(file,1) - p=xmllib.XMLParser() - p.start_handlers=F.start_handlers - p.end_handlers=F.end_handlers - p.handle_data=F.handle_data - p.unknown_starttag=F.unknown_starttag - p.unknown_endtag=F.unknown_endtag - p._stack=F._stack - p.push=F.push - p.append=F.append - p.file=F.file - p.tempfile=F.tempfile - data=string.split(q,'\n') - for l in data: - p.feed(l) - p.close() - z=p._stack - z=z[0][0] - print z, '\012' - -def test2(): import xml.parsers.expat - c=C() - c.foo=1 - c.bar=2 - x=[0,1,2,3] - y=('abc','abc',c,c) + import pickle + c = C() + c.foo = 1 + c.bar = 2 + x = [0, 1, 2, 3] + y = ('abc', 'abc', c, c) x.append(y) x.append(y) - t=() - l=[] - s='' + t = () + l = [] + s = '' L = long('999999999999') x.append(t) x.append(l) @@ -768,36 +679,21 @@ x.append(L) x.append(5) x.append(13) - print x, '\012' - f=pickle.dumps(x) - print f, '\012' - q=ToXMLloads(f) - q=str(q) - q='<?xml version="1.0"?>\n'+q - print q, '\012' - file='' - F=xmlPickler() - F.binary=0 - p=xml.parsers.expat.ParserCreate() - p.CharacterDataHandler=F.handle_data - p.StartElementHandler=F.unknown_starttag - p.EndElementHandler=F.unknown_endtag - r=p.Parse(q) - print r, '\012' + print x, '\n' + f = pickle.dumps(x) + print f, '\n' + q = ToXMLloads(f) + q = str(q) + q = '<?xml version="1.0"?>\n' + q + print q, '\n' + F = xmlPickler() + F.binary = 0 + p = xml.parsers.expat.ParserCreate() + p.CharacterDataHandler = F.handle_data + p.StartElementHandler = F.unknown_starttag + p.EndElementHandler = F.unknown_endtag + r = p.Parse(q) + print r, '\n' -def test3(): - import xml.parsers.expat - data=open('Data.xml').read() - file=open('out','w'+'b') - F=xmlPickler() - F.file=file - F.binary=1 - p=xml.parsers.expat.ParserCreate() - p.CharacterDataHandler=F.handle_data - p.StartElementHandler=F.unknown_starttag - p.EndElementHandler=F.unknown_endtag - r=p.Parse(data) - print r, '\012' - if __name__ == '__main__': test()
_______________________________________________ Zope-Checkins maillist - Zope-Checkins@zope.org https://mail.zope.org/mailman/listinfo/zope-checkins