我正在使用 python suds(版本:0.3.9 GA build:R659-20100219)与具有以下结构的 SOAP 服务进行交互:
服务 (DPWSService) tns="http://ejb.revitalization.services.ndg/" 前缀 (1) ns0 = "http://ejb.revitalization.services.ndg/" 端口 (1): (DPWS端口) 方法(13): addTimer(请求请求,) deleteProvider(请求请求,) deleteTimer(请求请求,) doHarvest(请求请求,) doIngest(请求请求,) doNewUpdateProvider(请求请求, ) getHarvestHistory(GetHistoryRequest 请求,) getIngestHistory(GetHistoryRequest 请求,) getList(GetListType 请求,) 获取列表名称() getProviderDetails(请求请求,) getProviderStatistic(请求请求,) getStatusProcess(请求请求, ) 类型 (63): 添加定时器响应 CSWProviderDetailsType 确认类型 联系人类型 数据范围类型 删除提供者响应 删除定时器响应 收获响应 摄取响应 DoNewUpdateProviderResponse 电子邮件联系人类型 获取HarvestHistoryResponse 获取历史请求 获取摄取历史响应 获取列表名称响应 获取列表响应 获取列表类型 获取进程状态响应 GetProviderDetailsResponse GetProviderStatisticResponse 收获历史类型 HarvestProviderType 收获类型 摄取历史类型 列表名称 OAIProviderDetailsType 进程ID类型 ProviderCommonType 提供者联系类型 提供者详情 ProviderDetailsType 提供者IDType 提供者统计 响应类型 TimerInfoCommonType 定时器信息详情 TimerInfoLogDetail 添加定时器 addTimerResponse 删除提供者 删除提供者响应 删除定时器 删除定时器响应 收获 收获回应 摄取 摄取响应 doNewUpdateProvider doNewUpdateProviderResponse 获取收获历史 getHarvestHistoryResponse 获取摄取历史 获取摄取历史响应 获取列表 获取列表名称 获取列表名称响应 获取列表响应 获取提供者详细信息 getProviderDetailsResponse 获取提供者统计 getProviderStatisticResponse 获取状态进程 getStatusProcessResponse
我需要发送一个结构如下的 SOAP 请求:
<SOAP-ENV:Envelope xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://
ejb.revitalization.services.ndg/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<ns0:Body>
<ns1:doIngest>
<request>
<ns1:ProcessID ns1:id="1430"/>
<ns1:EmailReportID>1031</ns1:EmailReportID>
</request>
</ns1:doIngest>
</ns0:Body>
</SOAP-ENV:Envelope>
也就是说,我需要在 id 属性前面附加目标命名空间。如果我不这样做,请求将失败:(
我尝试了几种方法来创建我的 doIngest 请求对象,但我只能创建如下请求:
<SOAP-ENV:Envelope xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://ejb.revitalization.services.ndg/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<ns0:Body>
<ns1:doIngest>
<request>
<ns1:ProcessID id="1441"/>
<ns1:EmailReportID>1031</ns1:EmailReportID>
</request>
</ns1:doIngest>
</ns0:Body>
</SOAP-ENV:Envelope>
也就是说,在 id 属性上没有目标命名空间前缀。
我尝试过以下变体:
request = wsClient.factory.create('doIngest.request')
request.EmailReportID = "1031"
request.ProcessID = wsClient.factory.create('ProcessIDType')
request.ProcessID._id= "1430"
result=wsClient.service.doIngest(request)
和:
request = wsClient.factory.create('{http://ejb.revitalization.services.ndg/}doIngest.request')
request.EmailReportID = "1031"
request.ProcessID = wsClient.factory.create('{http://ejb.revitalization.services.ndg/}ProcessIDType')
request.ProcessID._id="1430"
result=wsClient.service.doIngest(request)
和:
request = wsClient.factory.create('doIngest.request')
request.EmailReportID = emailIDs
request.ProcessID = wsClient.factory.create('ProcessIDType')
request.ProcessID._id = wsClient.factory.resolver.qualify('{http://ejb.revitalization.services.ndg/}_id')
request.ProcessID._id=procID
result=wsClient.service.doIngest(request)
但我得到了相同的 SOAP 请求
WSDL 告诉我:
<xs:complexType name="doIngest">
<xs:sequence>
<xs:element form="unqualified" minOccurs="0" name="request">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="ProcessID" type="tns:ProcessIDType"/>
<xs:element maxOccurs="unbounded" minOccurs="0" name="EmailReportID" type="xs:int"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
和
<xs:complexType name="ProcessIDType">
<xs:sequence/>
<xs:attribute ref="tns:id" use="required"/>
<xs:attribute ref="tns:status"/>
</xs:complexType>
这表明 id 确实需要命名空间前缀。
因此,问题是,如何将命名空间前缀强制到我的 id 属性上?
感谢甘地
因此解决方案是:
将 Suds 更新到 0.4(因为 MessagePlugin 在版本:0.3.9 中不可用)
然后:
class MyPlugin(MessagePlugin):
def marshalled(self, context):
ProcIDnode = context.envelope.getChild('Body').getChild('doIngest').getChild('request')[0]
#Get the value of the id attribute
ProcIDattVal = ProcIDnode.get('id')
#Remove the errant id, used as a tidy-up stage
ProcIDnode.unset('id')
#Get the namespace prefix for the target namespace
ProcIDnspref = ProcIDnode.findPrefix('http://ejb.revitalization.services.ndg/')
#Create the new attribute name with namespace prefix applied
newProcIDattname = ProcIDnspref + ':id'
#Insert the new attribute.
ProcIDnode.set(newProcIDattname,ProcIDattVal)