1

次のような suds を使用して、SOAP サーバーにリクエストを送信しようとしています。

<SOAP-ENV:Envelope xmlns:ns0="http://example.com/wsdl/abc/model/v1" xmlns:ns1="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns2="http://example.com/xsd/abc/common/v1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<ns1:Body>
   <ns0:myMethod>
      <unique_id>5211c04b-9cf5-4368-a393-ed96d7b5489d</unique_id>
      <metadata>
         <ns2:StringMetadata id="user">test_user</ns2:StringMetadata>
         <ns2:StringMetadata id="filename">myfile.zip</ns2:StringMetadata>
         <ns2:StringMetadata id="unique_id">5211c04b-9cf5-4368-a393-ed96d7b5489d</ns2:StringMetadata>
      </metadata>
   </ns0:myMethod>
</ns1:Body>

dictのみを使用してそれを行う方法はありますか?

私はこれを試しています:

params = {
'unique_id' : uid,
"metadata": {
        'StringMetadata' : ['test_user', 'myfile.zip']
    }
 }

 caller.myMethod(**params)

このリクエストを生成するもの:

    <SOAP-ENV:Envelope xmlns:ns0="http://example.com/wsdl/abc/model/v1" xmlns:ns1="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns2="http://example.com/xsd/abc/common/v1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Header/>
   <ns1:Body>
      <ns0:myMethod>
         <unique_id>2ae5a60e-7928-4d4f-9e53-bafe2a003b8a</unique_id>
         <metadata>
            <ns2:StringMetadata>test_user</ns2:StringMetadata>
            <ns2:StringMetadata>myfile.zip</ns2:StringMetadata>
         </metadata>
      </ns0:myMethod>
   </ns1:Body>
</SOAP-ENV:Envelope>

したがって、id属性がStringMetadaにないことがわかります。別の呼び出し元から検証されていない Json (または dict) を取得する一種の Rest to Soap プロキシを作成しているため、dictのみを使用して実行したいと考えています。したがって、可能な限り動的にする必要があります。

その場で要素を構築しようとしましたが (factory.create を使用)、頭痛の種のようです... 要素属性 ('_id'、'@id' または '#id') に特別なキーワードを渡すことで解決策をいただければ幸いです。 ')...

また、次のように StringMetadata を宣言しようとしました。

"metadata": {
        'StringMetadata' : [{'_id': 'user'}, 'myfile.zip']
    }

しかし、それは私に与えました:

    <ns2:StringMetadata id="user"/>
    <ns2:StringMetadata>myfile.zip</ns2:StringMetadata>

解決策がある場合は、サルのクラスに (オンザフライで) モンキー パッチを適用してください。

よろしく

4

1 に答える 1

0

何時間もの泡の理解とデバッグの後、ようやくそれを機能させることができました。suds monkey-patch に基づいたソリューションを作成しました。したがって、私の口述は次のようになります。

params = {
'unique_id' : uid,
"metadata": {
        'StringMetadata' : [{'_id': 'user', '_text_':'test_user'},{'_id': 'filename', '_text_': 'myfile.zip'}]
    }
 }

 caller.myMethod(**params)

' _text_ ' は、パッチによって検出され、ノード値として使用されるマジックです。' _id ' は属性として suds によって使用され、_ で始まるすべての要素はノード属性として解釈されるため、私のパッチは属性を処理しません。

これはパッチです:

import functools
from suds.mx.appender import *
legacy_append = suds.mx.appender.ObjectAppender.append
@functools.wraps(legacy_append)
def _patch_object_append(self, parent, content):
    object = content.value
    if self.optional(content) and footprint(object) == 0:
        return
    child = self.node(content)
    for item in object:
         cont = Content(tag=item[0], value=item[1])
         if item[0] == '_text_':
            child.setText(item[1])
            continue

         Appender.append(self, child, cont)
    parent.append(child)

suds.mx.appender.ObjectAppender.append= _patch_object_append

このブロックは、sud をインスタンス化する前に挿入するか、別のスクリプト ファイルに保存してスクリプトにインポートすることができます。個人的には、2番目のソリューションを使用しました。

また、キーワード テキストは私が選んだものであることに注意してください。代わりに' _value_ ' を使用できます。次の行で更新する必要があります。

     if item[0] == '_text_':

このパッチを自由に使用してください。この機能は Suds ライブラリに組み込むべきだと思います

よろしく、

于 2016-01-21T20:21:02.767 に答える