2

suds を使用してリモート SOAP サービスにリクエストを送信しようとしています。したがって、パラメーターに名前空間を設定する必要があります。

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:ns0="http://myemployer.com/"    xmlns:ns1="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Header>
      <AuthHeader xmlns="http://myemployer.com/">
            <Token>blah</Token>
      </AuthHeader>
   </SOAP-ENV:Header>
   <ns1:Body>
      <ns0:AwardBadgesBatch>
          <ns0:badgeAwards>
              <AwardBadge>
                  <EnterpriseID>jhoov11</EnterpriseID>
                  ...
              </AwardBadge>
         </ns0:badgeAwards>
         <ns0:includeSuccessStatus>false</ns0:includeSuccessStatus>
      </ns0:AwardBadgesBatch>
   </ns1:Body>   
</SOAP-ENV:Envelope>

BadgeAwards 要素と includeSuccessStatus 要素の両方の「ns0」に注意してください。また、badgeAwards 内のものにプレフィックスを付ける必要はありません。

私はこのコードを使用してリクエストを作成しています:

from suds.client import Client
from suds.sax.element import Element
from suds.sax.attribute import Attribute
from suds.plugin import MessagePlugin
import logging
logging.getLogger('suds.client').setLevel(logging.DEBUG)
logging.getLogger('suds.transport').setLevel(logging.DEBUG)
logging.basicConfig(level=logging.DEBUG)
url='https://myemployer.com/BadgingServices.asmx?wsdl'

c = Client(url)
t = c.service.Authenticate('blah')
t = t.Authenticate.Status.Token

header_root = Element('AuthHeader')
header_token = Element('Token').setText(t)
header_attribute = Attribute('xmlns', "http://myemployer.com/")
soap_header = header_root.insert(header_token)
soap_header.append(header_attribute)

class NamespaceFixer(MessagePlugin):
    ''' must add namespace prefix to all parameters '''
    def marshalled(self, context):
        body = context.envelope[1]
        for i in body[0]:
            i.setPrefix('ns0')
            print "******* element after setting prefix: %s ********" % i.plain()

nsf = NamespaceFixer()
c.set_options(soapheaders=soap_header, plugins=[nsf])

from suds.sax.element import Element

ba2 = Element('badgeAwards')
ba = Element('AwardBadge')
ba2.append(ba)
entid = Element('EnterpriseID').setText('jhoov11')
ba.append(entid)
...

includeSuccess = Element('includeSuccessStatus').setText('false')

c.service.AwardBadgesBatch(badgeAwards= ba2, includeSuccessStatus=includeSuccess)

これを行うと、marshall() 呼び出しの前に xml テキスト出力が表示され、その呼び出しからの出力が表示されます。

******* element after setting prefix: <ns0:badgeAwards/> ********
******* element after setting prefix: <ns0:includeSuccessStatus/> ********

しかし、反対側の人々は、それを受け取ったときにそれらの要素に接頭辞が設定されていないと主張します(主張します!)。

次の 2 つの質問が思い浮かびます。

  1. MessagePlugin で何か間違ったことをしていますか?
  2. 送信される前に、最終的に変更された XML テキストを表示する方法はありますか? 設定していると思いますが、送信する最終的な全文が表示されない場合、彼らに言えることは限られています。

編集:

c.last_sent().plain()
u'<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:ns0="http://pebble.searshc.com/" xmlns:ns1="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">

<SOAP-ENV:Header><AuthHeader xmlns="http://myemployer.com/"><Token>blah</Token></AuthHeader></SOAP-ENV:Header>
<ns1:Body><ns0:AwardBadgesBatch><ns0:badgeAwards/><ns0:includeSuccessStatus/></ns0:AwardBadgesBatch></ns1:Body></SOAP-ENV:Envelope>'

そのため、badgeAwards と includeSuccessStatus は空で送信されます。???

編集:工場を試しています。この wsdl は (私にとって) 奇妙です。呼び出し自体を型として定義しているため、次のようになります。

<s:element name="AwardBadgesBatch">
  <s:complexType>
    <s:sequence>
      <s:element minOccurs="0" maxOccurs="1" name="badgeAwards">
         <s:complexType mixed="true">
           <s:sequence>
              <s:any/>
           </s:sequence>
         </s:complexType>
      </s:element>
      <s:element minOccurs="1" maxOccurs="1" name="includeSuccessStatus" type="s:boolean"/>
    </s:sequence>
  </s:complexType>
</s:element>


...

<wsdl:operation name="AwardBadgesBatch">
  <soap:operation soapAction="http://pebble.searshc.com/AwardBadgesBatch" style="document"/>
  <wsdl:input>
    <soap:body use="literal"/>
    <soap:header message="tns:AwardBadgesBatchAuthHeader" part="AuthHeader" use="literal"/>
  </wsdl:input>
  <wsdl:output>
    <soap:body use="literal"/>
    <soap:header message="tns:AwardBadgesBatchAuthHeader" part="AuthHeader" use="literal"/>
  </wsdl:output>
</wsdl:operation>

AwardBadge タイプを定義しません。したがって、次のように AwardBadge を作成します。

ba = Element('AwardBadge')

entid = Element('EnterpriseID').setText('jhoov11')
ba.append(entid)
btype = Element('badgeTypeID').setText('30')
ba.append(btype)
startdate = Element('startDate').setText('2013-8-22')
ba.append(startdate)
enddate = Element('endDate').setText('9999-12-31')
ba.append(enddate)
isdeleted = Element('isDeleted').setText('0')
ba.append(isdeleted)

呼び出しに値を設定します

call = c.factory.create('AwardBadgesBatch')
call.badgeAwards= [ba]
call.includeSuccessStatus= False

そして私はサービスを呼び出します

c.service.AwardBadgesBatch(call)

そしていくつかのエラーが発生します。送ったものを見るとわかる

c.last_sent().plain()
u'<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:ns0="http://myemployer.com/" xmlns:ns1="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
  <SOAP-ENV:Header>
      <AuthHeader xmlns="http://myemployer.com/"><Token>blah</Token></AuthHeader>
  </SOAP-ENV:Header>
  <ns1:Body>
     <ns0:AwardBadgesBatch>
        <ns0:badgeAwards>
           <AwardBadge/>
           <ns0:includeSuccessStatus>false</ns0:includeSuccessStatus>
         </ns0:badgeAwards>
         <ns0:includeSuccessStatus/>
     </ns0:AwardBadgesBatch>
  </ns1:Body>
  </SOAP-ENV:Envelope>'

したがって、次の 3 つの問題があります。

  1. AwardBadge は空です。
  2. includeSuccessStatus が複製され、1 つが BadgeAwards 内にあり、属していません。
  3. 適切な場所にある includeSuccessStatus は空です。

BadgeAwards を ba に設定しても [ba] に設定しても違いはありません。

これ以上の洞察はありますか?

4

2 に答える 2

0

Suds はサービス タイプのファクトリを提供します - client.service.factory.create(type_name)。これにより、python オブジェクトが得られます。これがデモンストレーションです。ケースに合わせて調整できる場合があります。

...
client = Client(...)
award = client.factory.create("ns0:AwardBadgesBatch")
award.includeSuccessStatus = True
...

Suds には client.last_sent() と client.last_received() という 2 つの優れたメソッドがあります。リクエスト後にそれらを使用すると、正確に何を送受信したかを確認できます。また、サービス印刷の泡クライアントについて多くのことを知ることができます。

client = Client(...)
print client
于 2013-08-22T18:31:19.637 に答える