Improved XmlMarshaller: strings can be dumped as CDATA. Appy objects are marshalled with their history.
This commit is contained in:
parent
c3f5cfc9cd
commit
b888f8149b
|
@ -295,11 +295,11 @@ class AbstractWrapper:
|
||||||
if toDisk and not at:
|
if toDisk and not at:
|
||||||
at = getOsTempFolder() + '/' + self.o.UID() + '.xml'
|
at = getOsTempFolder() + '/' + self.o.UID() + '.xml'
|
||||||
# Create the XML version of the object
|
# Create the XML version of the object
|
||||||
xml = XmlMarshaller().marshall(self.o, objectType='archetype')
|
xml = XmlMarshaller(cdata=True).marshall(self.o, objectType='appy')
|
||||||
# Produce the desired result
|
# Produce the desired result
|
||||||
if toDisk:
|
if toDisk:
|
||||||
f = file(at, 'w')
|
f = file(at, 'w')
|
||||||
f.write(xml)
|
f.write(xml.encode('utf-8'))
|
||||||
f.close()
|
f.close()
|
||||||
return at
|
return at
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -336,14 +336,25 @@ class XmlMarshaller:
|
||||||
fieldsToExclude = []
|
fieldsToExclude = []
|
||||||
atFiles = ('image', 'file') # Types of archetypes fields that contain files.
|
atFiles = ('image', 'file') # Types of archetypes fields that contain files.
|
||||||
|
|
||||||
|
def __init__(self, cdata=False):
|
||||||
|
'''If p_cdata is True, all string values will be dumped as XML CDATA.'''
|
||||||
|
self.cdata = cdata
|
||||||
|
|
||||||
def dumpString(self, res, s):
|
def dumpString(self, res, s):
|
||||||
'''Dumps a string into the result.'''
|
'''Dumps a string into the result.'''
|
||||||
|
if self.cdata: res.write('<![CDATA[')
|
||||||
|
# Try to solve encoding problems
|
||||||
|
try:
|
||||||
|
s = s.decode('utf-8')
|
||||||
|
except UnicodeEncodeError:
|
||||||
|
pass
|
||||||
# Replace special chars by XML entities
|
# Replace special chars by XML entities
|
||||||
for c in s:
|
for c in s:
|
||||||
if self.xmlEntities.has_key(c):
|
if self.xmlEntities.has_key(c):
|
||||||
res.write(self.xmlEntities[c])
|
res.write(self.xmlEntities[c])
|
||||||
else:
|
else:
|
||||||
res.write(c)
|
res.write(c)
|
||||||
|
if self.cdata: res.write(']]>')
|
||||||
|
|
||||||
def dumpFile(self, res, v):
|
def dumpFile(self, res, v):
|
||||||
'''Dumps a file into the result.'''
|
'''Dumps a file into the result.'''
|
||||||
|
@ -428,10 +439,12 @@ class XmlMarshaller:
|
||||||
'''Returns in a StringIO the XML version of p_instance. If p_instance
|
'''Returns in a StringIO the XML version of p_instance. If p_instance
|
||||||
corresponds to a Plain Old Python Object, specify 'popo' for
|
corresponds to a Plain Old Python Object, specify 'popo' for
|
||||||
p_objectType. If p_instance corresponds to an Archetypes object
|
p_objectType. If p_instance corresponds to an Archetypes object
|
||||||
(Zope/Plone), specify 'archetype' for p_objectType.'''
|
(Zope/Plone), specify 'archetype' for p_objectType. if p_instance is
|
||||||
|
a Appy object, specify "appy" as p_objectType.'''
|
||||||
res = StringIO()
|
res = StringIO()
|
||||||
# Dump the XML prologue and root element
|
# Dump the XML prologue and root element
|
||||||
if objectType == 'archetype': objectId = instance.UID() # ID in DB
|
if objectType in ('archetype', 'appy'):
|
||||||
|
objectId = instance.UID() # ID in DB
|
||||||
else: objectId = str(id(instance)) # ID in RAM
|
else: objectId = str(id(instance)) # ID in RAM
|
||||||
res.write(self.xmlPrologue)
|
res.write(self.xmlPrologue)
|
||||||
res.write('<'); res.write(self.rootElementName)
|
res.write('<'); res.write(self.rootElementName)
|
||||||
|
@ -450,7 +463,7 @@ class XmlMarshaller:
|
||||||
mustDump = True
|
mustDump = True
|
||||||
if mustDump:
|
if mustDump:
|
||||||
self.dumpField(res, fieldName, fieldValue)
|
self.dumpField(res, fieldName, fieldValue)
|
||||||
elif objectType == 'archetype':
|
elif objectType in ('archetype', 'appy'):
|
||||||
fields = instance.schema.fields()
|
fields = instance.schema.fields()
|
||||||
for field in instance.schema.fields():
|
for field in instance.schema.fields():
|
||||||
# Dump only needed fields
|
# Dump only needed fields
|
||||||
|
@ -474,6 +487,17 @@ class XmlMarshaller:
|
||||||
fieldType = 'ref'
|
fieldType = 'ref'
|
||||||
self.dumpField(res, field.getName(), field.get(instance),
|
self.dumpField(res, field.getName(), field.get(instance),
|
||||||
fieldType=fieldType)
|
fieldType=fieldType)
|
||||||
|
if objectType == 'appy':
|
||||||
|
# Dump the object history.
|
||||||
|
res.write('<history type="list">')
|
||||||
|
wfInfo = instance.portal_workflow.getWorkflowsFor(instance)
|
||||||
|
if wfInfo:
|
||||||
|
history = instance.workflow_history[wfInfo[0].id]
|
||||||
|
for event in history:
|
||||||
|
res.write('<event type="object">')
|
||||||
|
for k, v in event.iteritems(): self.dumpField(res, k, v)
|
||||||
|
res.write('</event>')
|
||||||
|
res.write('</history>')
|
||||||
self.marshallSpecificElements(instance, res)
|
self.marshallSpecificElements(instance, res)
|
||||||
# Return the result
|
# Return the result
|
||||||
res.write('</'); res.write(self.rootElementName); res.write('>')
|
res.write('</'); res.write(self.rootElementName); res.write('>')
|
||||||
|
|
Loading…
Reference in a new issue