Sudsを使用してWebサービスと通信しようとしていますが、サービスからの読み取りは正常に機能しますが、書き込みはエラーをスローします。
suds.WebFault:サーバーで障害が発生しました:'メッセージの逆シリアル化の試行中にフォーマッタが例外をスローしました:パラメータhttp://tempuri.org/:tagValuesの逆シリアル化の試行中にエラーが発生しました。InnerExceptionメッセージは次のとおりです。'名前空間からの要素値 http://schemas.datacontract.org/2004/07/NOV.Api.Messagesには、オブジェクトとして逆シリアル化する子コンテンツを含めることはできません。XmlNode []を使用して、このXMLパターンを逆シリアル化します。詳細については、InnerExceptionを参照してください。
XMLが生成するものは、必要なxsi:type = "xsd:int"を追加していないようです。
生産:
<ns1:TagValue>
<ns1:Quality>
<ns1:Id>1</ns1:Id>
<ns1:QualityData>Quality</ns1:QualityData>
</ns1:Quality>
<ns1:TagID>
<ns1:Id>0</ns1:Id>
<ns1:TagID>BitDepth</ns1:TagID>
</ns1:TagID>
<ns1:Value>23</ns1:Value>
</ns1:TagValue>
期待される:
<ns1:TagValue>
<ns1:Quality>
<ns1:Id>1</ns1:Id>
<ns1:QualityData>Quality</ns1:QualityData>
</ns1:Quality>
<ns1:TagID>
<ns1:Id>0</ns1:Id>
<ns1:TagID>BitDepth</ns1:TagID>
</ns1:TagID>
<ns1:Value xsi:type="xsd:int">23</ns1:Value>
</ns1:TagValue>
周りを検索した後、私はImportDoctorを試して、xsi:typeに入ることができるかどうかを確認することにしました。
追加した
schema_url = 'http://schemas.xmlsoap.org/soap/encoding/'
schema_import = Import(schema_url)
schema_doctor = ImportDoctor(schema_import)
クライアントctorのdoctor=schema_doctor
これにより、追加のプレフィックスとタイプのはるかに拡張されたリストが得られました
Prefixes (4)
ns0 = "http://schemas.datacontract.org/2004/07/NOV.Api.Messages"
ns1 = "http://schemas.microsoft.com/2003/10/Serialization/"
ns2 = "http://schemas.xmlsoap.org/soap/encoding/"
ns3 = "http://tempuri.org/"
私は今ns2:intを持っています
ファクトリを使用して、ns2:int型のオブジェクトを作成し、その値を23に設定しました。
これを送信すると、次のXMLが表示されます。
<ns1:TagValue>
<ns1:Quality>
<ns1:Id>1</ns1:Id>
<ns1:QualityData>Quality</ns1:QualityData>
</ns1:Quality>
<ns1:TagID>
<ns1:Id>0</ns1:Id>
<ns1:TagID>BitDepth</ns1:TagID>
</ns1:TagID>
<ns1:Value xsi:type="ns2:int">23</ns1:Value>
</ns1:TagValue>
送信しようとすると、次の例外が発生します。
suds.WebFault:サーバーで障害が発生しました:'メッセージの逆シリアル化の試行中にフォーマッタが例外をスローしました:パラメータhttp://tempuri.org/:tagValuesの逆シリアル化の試行中にエラーが発生しました。InnerExceptionメッセージは「1行目の位置651のエラー」でした。要素「http://schemas.datacontract.org/2004/07/NOV.Api.Messages:Value」には、名前「http:/」にマップされるタイプのデータが含まれています。 /schemas.xmlsoap.org/soap/encoding/:int'。デシリアライザーは、この名前にマップされるタイプを認識していません。DataContractResolverの使用を検討するか、「int」に対応する型を既知の型のリストに追加します。たとえば、KnownTypeAttribute属性を使用するか、DataContractSerializerに渡される既知の型のリストに追加します。
少し近いように見えますが、名前空間に混乱があるようです。
生成された完全なXML:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:ns3="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns0="http://tempuri.org/" xmlns:ns1="http://schemas.datacontract.org/2004/07/NOV.Api.Messages" xmlns:ns2="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<ns3:Body>
<ns0:WriteRealtimeValues>
<ns0:tagValues>
<ns1:TagValue>
<ns1:Quality>
<ns1:Id>1</ns1:Id>
<ns1:QualityData>Quality</ns1:QualityData>
</ns1:Quality>
<ns1:TagID>
<ns1:Id>0</ns1:Id>
<ns1:TagID>BitDepth</ns1:TagID>
</ns1:TagID>
<ns1:Value xsi:type="ns2:int">23</ns1:Value>
</ns1:TagValue>
</ns0:tagValues>
</ns0:WriteRealtimeValues>
</ns3:Body>
</SOAP-ENV:Envelope>
参考までに、次のコードを使用してクライアントを作成します
credentials = dict(username='%s' % (username), password='%s' % password)
url= "http://%s:%s/TagValueWriteService?wsdl" % (ip,port)
self.transport = HttpAuthenticated(**credentials)
suds.client.Client.__init__(self,url, transport=self.transport, cache=None,doctor=schema_doctor)
ここスタックオーバーフローにはいくつかの同様の問題があるようですが、それらのほとんどは私が試したのと同じようにImportDoctorに言及しています。私はSOAPの基本的な理解の一部が不足していると思います...