Skip to content

Commit

Permalink
Refactor code so that a namespace lookup object is passed to all meth…
Browse files Browse the repository at this point in the history
…ods that need to qualify XML tags / attributes.

This change allows valid serialization of objects in isolation of the main framework in a manner that will produce fully valid XML.
  • Loading branch information
Jamie Kirkpatrick committed Feb 3, 2009
1 parent b684fa0 commit 01acb91
Show file tree
Hide file tree
Showing 15 changed files with 334 additions and 370 deletions.
7 changes: 7 additions & 0 deletions TODO.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Code to sort out after namespace map addition:

Message.to_xml()
ClassSerializerMeta.namespace

create_xml_element - pass nsmap
_add_messages_for_methods / _add_bindings_for_methods : create_xml_element (no nsmap)
18 changes: 11 additions & 7 deletions soaplib/serializers/binary.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import base64
import cStringIO
from soaplib.xml import *
from soaplib.xml import ns, create_xml_element

class Attachment(object):

Expand Down Expand Up @@ -36,7 +36,7 @@ def load_from_file(self):
f.close()

@classmethod
def to_xml(cls,value,name='retval'):
def to_xml(cls,value,name='retval',nsmap=ns):
'''This class method takes the data from the attachment and
base64 encodes it as the text of an Element. An attachment can
specify a filename and if no data is given, it will read the data
Expand All @@ -45,7 +45,7 @@ def to_xml(cls,value,name='retval'):
if value.__class__ is not Attachment:
raise Exception("Do not know how to serialize class %s"%type(value))

element = create_xml_element(name)
element = create_xml_element(name, nsmap)
if value.data:
# the data has already been loaded, just encode
# and return the element
Expand Down Expand Up @@ -79,14 +79,18 @@ def from_xml(cls,element):
return a

@classmethod
def get_datatype(cls,withNamespace=False):
def get_datatype(cls,nsmap=None):
'''Returns the datatype base64Binary'''
if withNamespace:
return 'xs:base64Binary'
if nsmap is not None:
return nsmap.get(cls.get_namespace_id()) + 'base64Binary'
return 'base64Binary'

@classmethod
def get_namespace_id(cls):
return 'xs'

@classmethod
def add_to_schema(cls,added_params):
def add_to_schema(cls,added_params,nsmap):
'''
Nothing needs to happen here as base64Binary is a standard
schema element
Expand Down
53 changes: 28 additions & 25 deletions soaplib/serializers/clazz.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import inspect
from soaplib.xml import *
from soaplib.xml import ns, create_xml_element, create_xml_subelement, qualify

from primitive import Null

Expand Down Expand Up @@ -43,8 +43,9 @@ def __init__(self):
setattr(self,k,None)

@classmethod
def to_xml(cls,value,name='retval'):
element = create_xml_element(qualify(name, cls.namespace))
def to_xml(cls,value,name='retval', nsmap=ns):
element = create_xml_element(
nsmap.get(cls.get_namespace_id()) + name, nsmap)

for k,v in cls.soap_members.items():
member_value = getattr(value,k,None)
Expand All @@ -53,7 +54,7 @@ def to_xml(cls,value,name='retval'):
if subvalue is None:
v = Null

subelements = v.to_xml(subvalue,name=k)
subelements = v.to_xml(subvalue,name=k,nsmap=nsmap)
if type(subelements) != list:
subelements = [subelements]
for s in subelements:
Expand All @@ -79,38 +80,40 @@ def from_xml(cls, element):
return obj

@classmethod
def get_datatype(cls,withNamespace=False):
if withNamespace:
return 'tns:%s'%(cls.__name__)
def get_datatype(cls,nsmap=None):
if nsmap is not None:
return nsmap.get(cls.get_namespace_id()) + cls.__name__
return cls.__name__


@classmethod
def get_namespace_id(cls):
return 'tns'

@classmethod
def add_to_schema(cls, schemaDict):
def add_to_schema(cls, schemaDict, nsmap):

if not schemaDict.has_key(cls.get_datatype(True)):
if not schemaDict.has_key(cls.get_datatype(nsmap)):
for k,v in cls.soap_members.items():
v.add_to_schema(schemaDict)
v.add_to_schema(schemaDict, nsmap)

tag = qualify("complexType", ns["xs"])
schema_node = create_xml_element(tag)
schema_node = create_xml_element(
nsmap.get("xs") + "complexType", nsmap)
schema_node.set('name',cls.__name__)

sequence_node = create_xml_subelement(
schema_node,
qualify('sequence', ns["xs"])
)
schema_node, nsmap.get('xs') + 'sequence')
for k,v in cls.soap_members.items():
member_node = create_xml_subelement(
sequence_node,
qualify('element', ns["xs"])
)
sequence_node, nsmap.get('xs') + 'element')
member_node.set('name',k)
member_node.set('minOccurs','0')
member_node.set('type',v.get_datatype(True))
member_node.set('type',
"%s:%s" % (v.get_namespace_id(), v.get_datatype()))

tag = qualify("element", ns["xs"])
typeElement = create_xml_element(tag)
typeElement = create_xml_element(
nsmap.get('xs') + 'element', nsmap)
typeElement.set('name',cls.__name__)
typeElement.set('type','tns:'+cls.__name__)
schemaDict[cls.get_datatype(True)+'Complex'] = schema_node
schemaDict[cls.get_datatype(True)] = typeElement
typeElement.set('type',
"%s:%s" % (cls.get_namespace_id(),cls.__name__))
schemaDict[cls.get_datatype(nsmap)+'Complex'] = schema_node
schemaDict[cls.get_datatype(nsmap)] = typeElement
Loading

0 comments on commit 01acb91

Please sign in to comment.