1.1 --- a/libxml2dom/xmlrpc.py Sun Sep 30 23:23:48 2007 +0000
1.2 +++ b/libxml2dom/xmlrpc.py Mon Oct 01 23:26:37 2007 +0000
1.3 @@ -80,6 +80,8 @@
1.4 return XMLRPCMemberElement(_node, self, context_node.ownerDocument)
1.5 elif Node_localName(_node) == "value":
1.6 return XMLRPCValueElement(_node, self, context_node.ownerDocument)
1.7 + elif Node_localName(_node) == "name":
1.8 + return XMLRPCNameElement(_node, self, context_node.ownerDocument)
1.9
1.10 # Otherwise, make generic XML-RPC elements.
1.11
1.12 @@ -102,19 +104,6 @@
1.13 def createMethodResponse(self):
1.14 return self.createXMLRPCMessage(None, "methodResponse")
1.15
1.16 -# Internal utility functions.
1.17 -
1.18 -def boolean(s):
1.19 - if s.lower() == "true":
1.20 - return True
1.21 - elif s.lower() == "false":
1.22 - return False
1.23 - else:
1.24 - raise ValueError, "String value %s not convertable to boolean." % repr(s)
1.25 -
1.26 -def iso8601(s):
1.27 - return s
1.28 -
1.29 # Node classes.
1.30
1.31 class XMLRPCNode(libxml2dom.Node):
1.32 @@ -134,35 +123,7 @@
1.33 "An XML-RPC document fragment."
1.34
1.35 def _method(self):
1.36 - return (self.xpath("./methodCall|./methodResponse") or [None])[0]
1.37 -
1.38 - method = property(_method)
1.39 -
1.40 - # Convenience methods and properties.
1.41 -
1.42 - def _methodName(self):
1.43 - if self.method is not None:
1.44 - return self.method.name
1.45 - else:
1.46 - return None
1.47 -
1.48 - def _parameterItems(self):
1.49 - if self.method is not None:
1.50 - return self.method.parameterItems
1.51 - else:
1.52 - return None
1.53 -
1.54 - def _parameterValues(self):
1.55 - if self.method is not None:
1.56 - return self.method.parameterValues
1.57 - else:
1.58 - return None
1.59 -
1.60 - def _parameterMap(self):
1.61 - if self.method is not None:
1.62 - return self.method.parameterMap
1.63 - else:
1.64 - return None
1.65 + return (self.xpath("methodCall|methodResponse") or [None])[0]
1.66
1.67 def _fault(self):
1.68 if self.method is not None:
1.69 @@ -170,6 +131,9 @@
1.70 else:
1.71 return None
1.72
1.73 + method = property(_method)
1.74 + fault = property(_fault)
1.75 +
1.76 # Node construction methods.
1.77
1.78 def createMethodCall(self):
1.79 @@ -178,12 +142,6 @@
1.80 def createMethodResponse(self):
1.81 return self.ownerDocument.createElement("methodResponse")
1.82
1.83 - methodName = property(_methodName)
1.84 - parameterItems = property(_parameterItems)
1.85 - parameterValues = property(_parameterValues)
1.86 - parameterMap = property(_parameterMap)
1.87 - fault = property(_fault)
1.88 -
1.89 class XMLRPCMethodElement(XMLRPCNode):
1.90
1.91 "An XML-RPC method element."
1.92 @@ -191,41 +149,41 @@
1.93 def _fault(self):
1.94 return (self.xpath("./fault") or [None])[0]
1.95
1.96 - def _methodName(self):
1.97 + def _methodNameElement(self):
1.98 return (self.xpath("./methodName") or [None])[0]
1.99
1.100 - def _name(self):
1.101 - name = self.methodName
1.102 + def _methodName(self):
1.103 + name = self.methodNameElement
1.104 if name is not None:
1.105 return name.value
1.106 else:
1.107 return None
1.108
1.109 - def _setName(self, name):
1.110 - if self.methodName is None:
1.111 + def _setMethodName(self, name):
1.112 + if self.methodNameElement is None:
1.113 methodName = self.createMethodName()
1.114 self.appendChild(methodName)
1.115 - self.methodName.value = name
1.116 + self.methodNameElement.value = name
1.117
1.118 def _parameters(self):
1.119 return self.xpath("./params/param")
1.120
1.121 - def _parameterItems(self):
1.122 + def _parameterValues(self):
1.123 values = self.xpath("./params/param/value")
1.124 if values:
1.125 items = []
1.126 for value in values:
1.127 - items.append(self._item_contents(value))
1.128 + items.append(self._get_value(value))
1.129 return items
1.130 else:
1.131 return []
1.132
1.133 - def _parameterValues(self):
1.134 - return self._value_contents(self.parameterItems)
1.135 -
1.136 def _setParameterValues(self, parameters):
1.137 param_list = self.parameters
1.138 params = (self.xpath("./params") or [None])[0]
1.139 +
1.140 + # Remove any previous parameters.
1.141 +
1.142 if params:
1.143 if param_list:
1.144 for param in param_list:
1.145 @@ -234,83 +192,46 @@
1.146 params = self.createParameters()
1.147 self.appendChild(params)
1.148
1.149 + # Add parameter values.
1.150 +
1.151 for parameter in parameters:
1.152 param = self.ownerDocument.createElement("param")
1.153 params.appendChild(param)
1.154 value = self.ownerDocument.createElement("value")
1.155 param.appendChild(value)
1.156 -
1.157 - # NOTE: Only handles simple types.
1.158 -
1.159 - container = self._make_container(parameter)
1.160 - value.appendChild(container)
1.161 - text = self.ownerDocument.createTextNode(unicode(parameter))
1.162 - container.appendChild(text)
1.163 -
1.164 - def _parameterMap(self):
1.165 - return self._map_contents(self.parameterItems)
1.166 -
1.167 - # Internal data.
1.168 -
1.169 - converters = {
1.170 - "string" : unicode,
1.171 - "int" : int,
1.172 - "i4" : int,
1.173 - "double" : float,
1.174 - "boolean" : boolean, # see the module globals
1.175 - "dateTime.iso8601" : iso8601, # see the module globals
1.176 - "base64" : str
1.177 - }
1.178 + self._add_value(value, parameter)
1.179
1.180 # Internal methods.
1.181
1.182 - def _make_container(self, parameter):
1.183 - if isinstance(parameter, (str, unicode)):
1.184 - return self.ownerDocument.createElement("string")
1.185 - elif isinstance(parameter, (int, long)):
1.186 - return self.ownerDocument.createElement("int")
1.187 - elif isinstance(parameter, float):
1.188 - return self.ownerDocument.createElement("double")
1.189 - elif isinstance(parameter, bool):
1.190 - return self.ownerDocument.createElement("boolean")
1.191 - elif isinstance(parameter, datetime.datetime):
1.192 - return self.ownerDocument.createElement("dateTime.iso8601")
1.193 + def _add_value(self, value, parameter):
1.194 + typename, parameter = parameter
1.195 + if typename == "struct":
1.196 + if isinstance(parameter, dict):
1.197 + items = parameter.items()
1.198 + else:
1.199 + items = parameter
1.200 + struct = self.ownerDocument.createElement("struct")
1.201 + for item_name, item_value in items:
1.202 + member = struct.createMember()
1.203 + struct.appendChild(member)
1.204 + member.memberName = item_name
1.205 + memberValue = member.createValue()
1.206 + member.appendChild(memberValue)
1.207 + self._add_value(memberValue, item_value)
1.208 + value.appendChild(struct)
1.209 + else:
1.210 + container = self.ownerDocument.createElement(typename)
1.211 + value.appendChild(container)
1.212 + container.value = unicode(parameter)
1.213
1.214 - def _from_string(self, typename, value):
1.215 - return self.converters.get(typename, str)(value)
1.216 -
1.217 - def _item_contents(self, value):
1.218 + def _get_value(self, value):
1.219 if value.type == "struct":
1.220 items = []
1.221 for member in value.container.members:
1.222 - if member.value.type == "struct":
1.223 - items.append((member.name, self._item_contents(member.value)))
1.224 - else:
1.225 - items.append((member.name, self._from_string(member.value.type, member.value.container.value)))
1.226 - return None, items
1.227 + items.append((member.memberName, self._get_value(member.value)))
1.228 + return (value.type, items)
1.229 else:
1.230 - return None, self._from_string(value.type, value.container.value)
1.231 -
1.232 - def _value_contents(self, items):
1.233 - values = []
1.234 - for name, value in items:
1.235 - if isinstance(value, list):
1.236 - values.append(self._value_contents(value))
1.237 - elif name is None:
1.238 - values.append(value)
1.239 - else:
1.240 - values.append((name, value))
1.241 - return values
1.242 -
1.243 - def _map_contents(self, items):
1.244 - d = {}
1.245 - for n, (name, value) in enumerate(items):
1.246 - key_name = name or str(n)
1.247 - if isinstance(value, list):
1.248 - d[key_name] = self._map_contents(value)
1.249 - else:
1.250 - d[key_name] = value
1.251 - return d
1.252 + return (value.type, value.container.value)
1.253
1.254 # Node construction methods.
1.255
1.256 @@ -324,12 +245,58 @@
1.257 return self.ownerDocument.createElement("fault")
1.258
1.259 fault = property(_fault)
1.260 - name = property(_name, _setName)
1.261 - methodName = property(_methodName)
1.262 + methodNameElement = property(_methodNameElement)
1.263 + methodName = property(_methodName, _setMethodName)
1.264 parameters = property(_parameters)
1.265 - parameterItems = property(_parameterItems)
1.266 parameterValues = property(_parameterValues, _setParameterValues)
1.267 - parameterMap = property(_parameterMap)
1.268 +
1.269 +class XMLRPCStructElement(XMLRPCNode):
1.270 +
1.271 + "An XML-RPC structure element."
1.272 +
1.273 + def _members(self):
1.274 + return self.xpath("./member")
1.275 +
1.276 + # Node construction methods.
1.277 +
1.278 + def createMember(self):
1.279 + return self.ownerDocument.createElement("member")
1.280 +
1.281 + members = property(_members)
1.282 +
1.283 +class XMLRPCMemberElement(XMLRPCNode):
1.284 +
1.285 + "An XML-RPC structure member element."
1.286 +
1.287 + def _nameElement(self):
1.288 + return (self.xpath("./name") or [None])[0]
1.289 +
1.290 + def _memberName(self):
1.291 + if self.nameElement is not None:
1.292 + return self.nameElement.value
1.293 + else:
1.294 + return None
1.295 +
1.296 + def _setMemberName(self, name):
1.297 + if self.nameElement is None:
1.298 + nameElement = self.createName()
1.299 + self.appendChild(nameElement)
1.300 + self.nameElement.value = name
1.301 +
1.302 + def _value(self):
1.303 + return (self.xpath("./value") or [None])[0]
1.304 +
1.305 + # Node construction methods.
1.306 +
1.307 + def createName(self):
1.308 + return self.ownerDocument.createElement("name")
1.309 +
1.310 + def createValue(self):
1.311 + return self.ownerDocument.createElement("value")
1.312 +
1.313 + nameElement = property(_nameElement)
1.314 + memberName = property(_memberName, _setMemberName)
1.315 + value = property(_value)
1.316
1.317 class XMLRPCStringElement(XMLRPCNode):
1.318
1.319 @@ -346,6 +313,12 @@
1.320
1.321 value = property(_value, _setValue)
1.322
1.323 +class XMLRPCNameElement(XMLRPCStringElement):
1.324 +
1.325 + "An XML-RPC name element."
1.326 +
1.327 + pass
1.328 +
1.329 class XMLRPCValueElement(XMLRPCStringElement):
1.330
1.331 "An XML-RPC value element."
1.332 @@ -399,32 +372,6 @@
1.333
1.334 pass
1.335
1.336 -class XMLRPCStructElement(XMLRPCNode):
1.337 -
1.338 - "An XML-RPC structure element."
1.339 -
1.340 - def _members(self):
1.341 - return self.xpath("./member")
1.342 -
1.343 - members = property(_members)
1.344 -
1.345 -class XMLRPCMemberElement(XMLRPCNode):
1.346 -
1.347 - "An XML-RPC structure member element."
1.348 -
1.349 - def _name(self):
1.350 - value = self.xpath("./name")
1.351 - if value:
1.352 - return value[0].textContent.strip()
1.353 - else:
1.354 - return None
1.355 -
1.356 - def _value(self):
1.357 - return (self.xpath("./value") or [None])[0]
1.358 -
1.359 - name = property(_name)
1.360 - value = property(_value)
1.361 -
1.362 class XMLRPCFaultElement(XMLRPCNode):
1.363
1.364 "An XML-RPC fault element."