[英]How do I force a namespace prefix on an attibute in a SOAP request created using suds
[英]python suds wrong namespace prefix in SOAP request
我使用python / suds來實現一個客戶端,我在發送的SOAP頭中得到錯誤的名稱空間前綴,用於wsdl中由element ref=
定義的特定參數類型。
.wsdl引用了數據類型.xsd文件,如下所示。 問題在於GetRecordAttributes
函數及其第一個類型為gbt:recordReferences
參數。
文件:browse2.wsdl
<xsd:schema targetNamespace="http://www.grantadesign.com/10/10/Browse" xmlns="http://www.grantadesign.com/10/10/Browse" xmlns:gbt="http://www.grantadesign.com/10/10/GrantaBaseTypes" elementFormDefault="qualified" attributeFormDefault="qualified">
<xsd:import schemaLocation="grantabasetypes2.xsd" namespace="http://www.grantadesign.com/10/10/GrantaBaseTypes"/>
<xsd:element name="GetRecordAttributes">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="gbt:recordReferences">
</xsd:element>
引用文件:grantabasetypes2.xsd
<element name="recordReferences">
<complexType>
<sequence>
<element name="record" minOccurs="0" maxOccurs="unbounded" type="gbt:MIRecordReference"/>
</sequence>
</complexType>
</element>
suds發送的SOAP請求:
<SOAP-ENV:Envelope xmlns:ns0="http://www.grantadesign.com/10/10/GrantaBaseTypes" xmlns:ns1="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns2="http://www.grantadesign.com/10/10/Browse" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<ns1:Body>
<ns2:GetRecordAttributes>
<ns2:recordReferences>
<ns0:record>
</ns0:record>
</ns2:recordReferences>
</ns2:GetRecordAttributes>
</ns1:Body>
</SOAP-ENV:Envelope>
問題 : <ns2:recordReferences>
有錯誤的前綴,應該是<ns0:recordReferences>
因為它屬於命名空間...GrantaBaseTypes
定義的...GrantaBaseTypes
。
對於wsdl中ref=
定義的所有參數,都會發生這種情況。 如何自動修復?
注意:我通過curl手動發送xml SOAP請求,檢查了服務是否接受了“good”前綴。
UPDATE
我使用SUDS源代碼進行干預,並且以下經驗修復強制所有帶有ref=
attribute的元素都假定引用的命名空間(以前,它們采用模式根命名空間或任何tns
):
文件:/suds/xsd/sxbase.py
class SchemaObject(object):
....
def namespace(self, prefix=None):
ns = self.schema.tns
#FIX BEGIN
if self.ref and self.ref in self.schema.elements.keys():
ns = self.ref
#FIX END
適用於我的服務,但我不確定它是否會破壞其他東西。 我更喜歡更智能的解決方案,它不會改變SUDS源代碼。
謝謝,
亞歷克斯
編寫一個Suds插件 ,在發送之前修改XML。
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()])
引用Suds文檔:
整理()
為插件提供在發送之前檢查/修改信封文檔的機會。
使用suds訪問BizTalk / IIS SOAP服務時,我遇到了完全相同的問題。 從我從WSDL中可以看出,當有一個“complexType”不屬於“targetNamespace”(它有自己的一部分)時,就會發生這種情況,它有一個子類,它也是一個complexType,但沒有設置名稱空間。 在BizTalk中,這意味着子項應該與父項屬於同一名稱空間,但是Suds似乎認為它應該是targetNamespace的一部分....
源代碼中的修復解決了“正確”的問題,但是因為我希望每次去另一個解決方案時能夠升級而不應用修復程序....
我的解決方案是跳過Suds並只復制原始XML,將其用作模板並將值復制到其中...不漂亮,但至少簡單。 在我看來,添加插件的解決方案同樣硬編碼,甚至可能更難維護。
您可以自己構建soap消息並使用SoapClient
發送消息:
sc = SoapClient(cli.service.XXXMethod.client,cli.service.XXXMethod.method)
sc.send(some_soap_doc)
我更喜歡正則表達式:)
import re
class EnvelopeFixer(MessagePlugin):
def sending(self, context):
# rimuovi i prefissi
context.envelope = re.sub( 'ns[0-9]:', '', context.envelope )
return context.envelope
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.