1.1 --- a/libxml2dom/xmlrpc.py Mon Oct 01 23:27:18 2007 +0000
1.2 +++ b/libxml2dom/xmlrpc.py Sat Oct 06 19:33:22 2007 +0000
1.3 @@ -32,7 +32,7 @@
1.4 from libxml2dom.macrolib import *
1.5 from libxml2dom.macrolib import \
1.6 createDocument as Node_createDocument
1.7 -import datetime
1.8 +from libxml2dom.rpc import ParameterName
1.9
1.10 class XMLRPCImplementation(libxml2dom.Implementation):
1.11
1.12 @@ -82,6 +82,10 @@
1.13 return XMLRPCValueElement(_node, self, context_node.ownerDocument)
1.14 elif Node_localName(_node) == "name":
1.15 return XMLRPCNameElement(_node, self, context_node.ownerDocument)
1.16 + elif Node_localName(_node) == "array":
1.17 + return XMLRPCArrayElement(_node, self, context_node.ownerDocument)
1.18 + elif Node_localName(_node) == "data":
1.19 + return XMLRPCDataElement(_node, self, context_node.ownerDocument)
1.20
1.21 # Otherwise, make generic XML-RPC elements.
1.22
1.23 @@ -168,7 +172,7 @@
1.24 def _parameters(self):
1.25 return self.xpath("./params/param")
1.26
1.27 - def _parameterValues(self):
1.28 + def _rawParameterValues(self):
1.29 values = self.xpath("./params/param/value")
1.30 if values:
1.31 items = []
1.32 @@ -178,7 +182,7 @@
1.33 else:
1.34 return []
1.35
1.36 - def _setParameterValues(self, parameters):
1.37 + def _setRawParameterValues(self, parameters):
1.38 param_list = self.parameters
1.39 params = (self.xpath("./params") or [None])[0]
1.40
1.41 @@ -201,37 +205,90 @@
1.42 param.appendChild(value)
1.43 self._add_value(value, parameter)
1.44
1.45 + def _parameterValues(self):
1.46 + return libxml2dom.rpc.convert(self.rawParameterValues)
1.47 +
1.48 # Internal methods.
1.49
1.50 def _add_value(self, value, parameter):
1.51 - typename, parameter = parameter
1.52 +
1.53 + "Add to the 'value' element the given 'parameter'."
1.54 +
1.55 + (typename, parameter_name), parameter_value = parameter
1.56 +
1.57 if typename == "struct":
1.58 - if isinstance(parameter, dict):
1.59 - items = parameter.items()
1.60 + if isinstance(parameter_value, dict):
1.61 + items = parameter_value.items()
1.62 else:
1.63 - items = parameter
1.64 + items = parameter_value
1.65 +
1.66 + # Create a struct element and add the members.
1.67 +
1.68 struct = self.ownerDocument.createElement("struct")
1.69 - for item_name, item_value in items:
1.70 + value.appendChild(struct)
1.71 +
1.72 + for item in items:
1.73 + (item_typename, item_name), item_value = item
1.74 member = struct.createMember()
1.75 struct.appendChild(member)
1.76 +
1.77 + # Peek into the item to set up the name.
1.78 +
1.79 member.memberName = item_name
1.80 +
1.81 + # Add the item inside a new value element.
1.82 +
1.83 memberValue = member.createValue()
1.84 member.appendChild(memberValue)
1.85 - self._add_value(memberValue, item_value)
1.86 - value.appendChild(struct)
1.87 + self._add_value(memberValue, item)
1.88 +
1.89 + elif typename == "array":
1.90 +
1.91 + # Create an array element and add the members.
1.92 +
1.93 + array = self.ownerDocument.createElement("array")
1.94 + value.appendChild(array)
1.95 + data = array.createData()
1.96 + array.appendChild(data)
1.97 +
1.98 + for item in parameter_value:
1.99 +
1.100 + # Add the item inside a new value element.
1.101 +
1.102 + data_value = data.createValue()
1.103 + data.appendChild(data_value)
1.104 + self._add_value(data_value, item)
1.105 +
1.106 else:
1.107 container = self.ownerDocument.createElement(typename)
1.108 value.appendChild(container)
1.109 - container.value = unicode(parameter)
1.110 + container.value = unicode(parameter_value)
1.111 +
1.112 + def _get_value(self, value, name=None):
1.113
1.114 - def _get_value(self, value):
1.115 + """
1.116 + Return the parameter name and value from within the given 'value'
1.117 + element, using the optional 'name' as part of the returned name if
1.118 + specified.
1.119 + """
1.120 +
1.121 if value.type == "struct":
1.122 items = []
1.123 +
1.124 + # Peek inside member values to get member names.
1.125 +
1.126 for member in value.container.members:
1.127 - items.append((member.memberName, self._get_value(member.value)))
1.128 - return (value.type, items)
1.129 + items.append(self._get_value(member.value, member.memberName))
1.130 + return (ParameterName(value.type, name), items)
1.131 +
1.132 + elif value.type == "array":
1.133 + items = []
1.134 + for data_value in value.container.data.values:
1.135 + items.append(self._get_value(data_value))
1.136 + return (ParameterName(value.type, name), items)
1.137 +
1.138 else:
1.139 - return (value.type, value.container.value)
1.140 + return (ParameterName(value.type, name), value.container.value)
1.141
1.142 # Node construction methods.
1.143
1.144 @@ -248,7 +305,22 @@
1.145 methodNameElement = property(_methodNameElement)
1.146 methodName = property(_methodName, _setMethodName)
1.147 parameters = property(_parameters)
1.148 - parameterValues = property(_parameterValues, _setParameterValues)
1.149 + rawParameterValues = property(_rawParameterValues, _setRawParameterValues)
1.150 + parameterValues = property(_parameterValues)
1.151 +
1.152 +class XMLRPCArrayElement(XMLRPCNode):
1.153 +
1.154 + "An XML-RPC array element."
1.155 +
1.156 + def _data(self):
1.157 + return (self.xpath("./data") or [None])[0]
1.158 +
1.159 + # Node construction methods.
1.160 +
1.161 + def createData(self):
1.162 + return self.ownerDocument.createElement("data")
1.163 +
1.164 + data = property(_data)
1.165
1.166 class XMLRPCStructElement(XMLRPCNode):
1.167
1.168 @@ -264,10 +336,27 @@
1.169
1.170 members = property(_members)
1.171
1.172 +class XMLRPCDataElement(XMLRPCNode):
1.173 +
1.174 + "An XML-RPC array data element."
1.175 +
1.176 + def _values(self):
1.177 + return self.xpath("./value")
1.178 +
1.179 + values = property(_values)
1.180 +
1.181 + # Node construction methods.
1.182 +
1.183 + def createValue(self):
1.184 + return self.ownerDocument.createElement("value")
1.185 +
1.186 class XMLRPCMemberElement(XMLRPCNode):
1.187
1.188 "An XML-RPC structure member element."
1.189
1.190 + def _value(self):
1.191 + return (self.xpath("./value") or [None])[0]
1.192 +
1.193 def _nameElement(self):
1.194 return (self.xpath("./name") or [None])[0]
1.195
1.196 @@ -283,9 +372,6 @@
1.197 self.appendChild(nameElement)
1.198 self.nameElement.value = name
1.199
1.200 - def _value(self):
1.201 - return (self.xpath("./value") or [None])[0]
1.202 -
1.203 # Node construction methods.
1.204
1.205 def createName(self):
1.206 @@ -294,9 +380,9 @@
1.207 def createValue(self):
1.208 return self.ownerDocument.createElement("value")
1.209
1.210 + value = property(_value)
1.211 nameElement = property(_nameElement)
1.212 memberName = property(_memberName, _setMemberName)
1.213 - value = property(_value)
1.214
1.215 class XMLRPCStringElement(XMLRPCNode):
1.216