python suds wrong namespace prefix in SOAP request

故事扮演 提交于 2019-11-30 07:33:21

Write a Suds plugin to modify the XML before it is sent.

from suds.client import Client
from suds.plugin import MessagePlugin

class MyPlugin(MessagePlugin):
    def marshalled(self, context):
        #modify this line to reliably find the "recordReferences" element
        context.envelope[1][0][0].setPrefix('ns0')

client = Client(WSDL_URL, plugins=[MyPlugin()])

Quoting Suds documentation:

marshalled()
Provides the plugin with the opportunity to inspect/modify the envelope Document before it is sent.

I had the exact same problem when using suds to access a BizTalk/IIS SOAP service. From what I can tell from the WSDL it occurs when there is a "complexType" that is not part of the "targetNamespace" (it has it's own), which has a child that is also a complexType, but with no namespace set. In BizTalk this means that the child should belong to the same namespace as the parent, but Suds seem to think that it then should be part of the targetNamespace ....

The fix in the source-code solved the thing "correctly", but since I want to be able to upgrade without applying the fix every time I went for another solution....

My solution was to skip Suds and just copy the raw XML, use that as a template and copy the values into it ... Not beautiful, but at least simple. The solution to add a plugin is in my opinion equally hardcoded and perhaps even harder to maintain.

Jun Li

You could build soap message yourself and use SoapClient to send the message :

sc = SoapClient(cli.service.XXXMethod.client,cli.service.XXXMethod.method)
sc.send(some_soap_doc)

I prefer regular expressions :)

import re

class EnvelopeFixer(MessagePlugin):
    def sending(self, context):
        # rimuovi i prefissi
        context.envelope = re.sub( 'ns[0-9]:', '', context.envelope )
        return context.envelope
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!