1.1 --- a/libxml2dom/soap.py Sun Sep 30 00:57:06 2007 +0000
1.2 +++ b/libxml2dom/soap.py Sun Sep 30 23:23:40 2007 +0000
1.3 @@ -134,6 +134,29 @@
1.4
1.5 envelope = property(_envelope)
1.6
1.7 + # Convenience methods and properties.
1.8 +
1.9 + def _methodName(self):
1.10 + return self.envelope.body.methodName
1.11 +
1.12 + def _parameterItems(self):
1.13 + return self.envelope.body.parameterItems
1.14 +
1.15 + def _parameterValues(self):
1.16 + return self.envelope.body.parameterValues
1.17 +
1.18 + def _parameterMap(self):
1.19 + return self.envelope.body.parameterMap
1.20 +
1.21 + def _fault(self):
1.22 + return self.envelope.body.fault
1.23 +
1.24 + methodName = property(_methodName)
1.25 + parameterItems = property(_parameterItems)
1.26 + parameterValues = property(_parameterValues)
1.27 + parameterMap = property(_parameterMap)
1.28 + fault = property(_fault)
1.29 +
1.30 class SOAPElement(SOAPNode):
1.31
1.32 "A SOAP element."
1.33 @@ -169,30 +192,84 @@
1.34 "A SOAP body element."
1.35
1.36 def _fault(self):
1.37 - return self.xpath("./env:Fault")[0]
1.38 + return (self.xpath("./env:Fault") or [None])[0]
1.39
1.40 def _method(self):
1.41 - return self.xpath("./*[@env:encodingStyle = '%s']" % SOAP_ENCODING_NAMESPACE)[0]
1.42 + return (self.xpath("./*[@env:encodingStyle = '%s']" % SOAP_ENCODING_NAMESPACE) or [None])[0]
1.43
1.44 def _methodName(self):
1.45 - return self.method.localName
1.46 + if self.method is not None:
1.47 + return self.method.localName
1.48 + else:
1.49 + return None
1.50
1.51 def _resultParameter(self):
1.52 - return self.method.xpath(".//rpc:result")[0]
1.53 + return (self.method.xpath(".//rpc:result") or [None])[0]
1.54
1.55 def _resultParameterValue(self):
1.56 - name = self.resultParameter.textContent.strip()
1.57 - return self.method.xpath(".//%s" % name, namespaces={self.method.prefix : self.method.namespaceURI})[0].textContent.strip()
1.58 + if self.resultParameter:
1.59 + name = self.resultParameter.textContent.strip()
1.60 + result = self.method.xpath(".//%s" % name, namespaces={self.method.prefix : self.method.namespaceURI})
1.61 + if result:
1.62 + return result[0].textContent.strip()
1.63 + else:
1.64 + return None
1.65 + else:
1.66 + return None
1.67
1.68 def _parameters(self):
1.69 - return self.method.xpath(".//*[not(./*)]")
1.70 + if self.method is not None:
1.71 + return self.method.xpath("*")
1.72 + else:
1.73 + return []
1.74 +
1.75 + def _parameterItems(self):
1.76 + values = []
1.77 + for parameter in self.parameters:
1.78 + values.append(self._item_contents(parameter))
1.79 + return values
1.80
1.81 def _parameterValues(self):
1.82 - values = {}
1.83 - for parameter in self.parameters:
1.84 - values[(parameter.namespaceURI, parameter.localName)] = parameter.textContent.strip()
1.85 + return self._value_contents(self.parameterItems)
1.86 +
1.87 + def _parameterMap(self):
1.88 + return self._map_contents(self.parameterItems)
1.89 +
1.90 + # Internal methods.
1.91 +
1.92 + def _item_contents(self, parameter):
1.93 + elements = parameter.xpath("*")
1.94 + if elements:
1.95 + items = []
1.96 + for element in elements:
1.97 + items.append(self._item_contents(element))
1.98 + return (parameter.namespaceURI, parameter.localName), items
1.99 + else:
1.100 + return (parameter.namespaceURI, parameter.localName), parameter.textContent.strip()
1.101 +
1.102 + def _value_contents(self, items):
1.103 + values = []
1.104 + for (typename, name), value in items:
1.105 + if isinstance(value, list):
1.106 + values.append(self._value_contents(value))
1.107 + elif name is None:
1.108 + values.append(value)
1.109 + else:
1.110 + values.append((name, value))
1.111 return values
1.112
1.113 + def _map_contents(self, items):
1.114 + d = {}
1.115 + for n, ((typename, name), value) in enumerate(items):
1.116 + key_name = name or str(n)
1.117 + if isinstance(value, list):
1.118 + d[(typename, key_name)] = self._map_contents(value)
1.119 + else:
1.120 + d[(typename, key_name)] = value
1.121 + return d
1.122 +
1.123 + # Node construction methods.
1.124 +
1.125 def createFault(self):
1.126 return self.ownerDocument.createElementNS(SOAP_ENVELOPE_NAMESPACE, "env:Fault")
1.127
1.128 @@ -202,25 +279,39 @@
1.129 resultParameter = property(_resultParameter)
1.130 resultParameterValue = property(_resultParameterValue)
1.131 parameters = property(_parameters)
1.132 + parameterItems = property(_parameterItems)
1.133 parameterValues = property(_parameterValues)
1.134 + parameterMap = property(_parameterMap)
1.135
1.136 class SOAPFaultElement(SOAPNode):
1.137
1.138 "A SOAP fault element."
1.139
1.140 def _code(self):
1.141 - return self.xpath("./env:Code")[0]
1.142 + code = self.xpath("./env:Code")
1.143 + if code:
1.144 + return code[0].value
1.145 + else:
1.146 + return None
1.147 +
1.148 + def _subcode(self):
1.149 + subcode = self.xpath("./env:Code/env:Subcode")
1.150 + if subcode:
1.151 + return subcode[0].value
1.152 + else:
1.153 + return None
1.154
1.155 def _reason(self):
1.156 - return self.xpath("./env:Reason")[0]
1.157 + return (self.xpath("./env:Reason") or [None])[0]
1.158
1.159 def _detail(self):
1.160 - return self.xpath("./env:Detail")[0]
1.161 + return (self.xpath("./env:Detail") or [None])[0]
1.162
1.163 def createCode(self):
1.164 return self.ownerDocument.createElementNS(SOAP_ENVELOPE_NAMESPACE, "env:Code")
1.165
1.166 code = property(_code)
1.167 + subcode = property(_subcode)
1.168 reason = property(_reason)
1.169 detail = property(_detail)
1.170
1.171 @@ -229,7 +320,11 @@
1.172 "A SOAP subcode element."
1.173
1.174 def _value(self):
1.175 - return self.xpath("./env:Value")[0].textContent.strip()
1.176 + value = self.xpath("./env:Value")
1.177 + if value:
1.178 + return value[0].textContent.strip()
1.179 + else:
1.180 + return None
1.181
1.182 def _setValue(self, value):
1.183 nodes = self.xpath("./env:Value")
1.184 @@ -253,7 +348,7 @@
1.185 "A SOAP code element."
1.186
1.187 def _subcode(self):
1.188 - return self.xpath("./env:Subcode")[0]
1.189 + return (self.xpath("./env:Subcode") or [None])[0]
1.190
1.191 def createSubcode(self):
1.192 return self.ownerDocument.createElementNS(SOAP_ENVELOPE_NAMESPACE, "env:Subcode")