питон / пена. как использовать ImportDoctor, чтобы избежать внедрения схемы и типа с маршалом - PullRequest
0 голосов
/ 28 октября 2019

у меня есть этот метод на wsdl

<xs:element name="checkIndicePdV">
<xs:complexType>
<xs:sequence>
<xs:element xmlns:q4="http://schemas.microsoft.com/2003/10/Serialization/Arrays" minOccurs="0" name="properties" nillable="true" type="q4:ArrayOfKeyValueOfstringanyType"/>
<xs:element xmlns:q5="http://docs.oasis-open.org/ns/cmis/core/200908/" minOccurs="0" name="contentStream" nillable="true" type="q5:ContentStream"/>
</xs:sequence>
</xs:complexType>
</xs:element>

, где выполняется этот код

    answer = fixed_client.service.checkIndicePdV(
        properties=properties,
        contentStream=content_stream
    )

я получаю это исключение

suds.WebFault: b"Server raised fault: 'The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org/:properties. The InnerException message was 'Element Value from namespace http://schemas.microsoft.com/2003/10/Serialization/Arrays cannot have child contents to be deserialized as an object. Please use XmlNode[] to deserialize this pattern of XML.'.  Please see InnerException for more details.'"

читая множество статей напереполнение стека, я понимаю, я могу это исправить с помощью ImportDoctor.

я пытался использовать Import Doctor

imp = Import("http://schemas.microsoft.com/2003/10/Serialization/Arrays")
    imp.filter.add("http://tempuri.org/:properties")
    doctor = ImportDoctor(imp)

    fixed_client = SudsClient("xxx?singleWsdl",username=xxx, password=xxx, doctor=doctor)

answer = fixed_client.service.checkIndicePdV(
        properties=properties,
        contentStream=content_stream
    )

ничего не изменилось.

я решил с помощью плагина

from suds.plugin import MessagePlugin
class FixSchema(MessagePlugin):
    def marshalled(self, context):

        if context.envelope.childAtPath("Body/createDocument/") is not None:
            context.envelope.getChild('Body').getChild('createDocument').getChild('properties')[0].getChild('Value').set('xmlns:c','http://www.w3.org/2001/XMLSchema')
            context.envelope.getChild('Body').getChild('createDocument').getChild('properties')[0].getChild('Value').set('i:type','c:boolean')
            context.envelope.getChild('Body').getChild('createDocument').getChild('properties')[1].getChild('Value').set('xmlns:c','http://www.w3.org/2001/XMLSchema')
            context.envelope.getChild('Body').getChild('createDocument').getChild('properties')[1].getChild('Value').set('i:type','c:boolean')
            context.envelope.getChild('Body').getChild('createDocument').getChild('properties').set('xmlns:i','http://www.w3.org/2001/XMLSchema-instance')

        if context.envelope.childAtPath("Body/checkIndicePdV/") is not None:
            context.envelope.getChild('Body').getChild('checkIndicePdV').getChild('properties')[0].getChild('Value').set('xmlns:c','http://www.w3.org/2001/XMLSchema')
            context.envelope.getChild('Body').getChild('checkIndicePdV').getChild('properties')[0].getChild('Value').set('i:type','c:boolean')
            context.envelope.getChild('Body').getChild('checkIndicePdV').getChild('properties')[1].getChild('Value').set('xmlns:c','http://www.w3.org/2001/XMLSchema')
            context.envelope.getChild('Body').getChild('checkIndicePdV').getChild('properties')[1].getChild('Value').set('i:type','c:boolean')
            context.envelope.getChild('Body').getChild('checkIndicePdV').getChild('properties').set('xmlns:i','http://www.w3.org/2001/XMLSchema-instance')

но, как вы видите, мне нужно обрабатывать одно и то же исправление для разных методов.

Я думаю, что правильный способ исправить это - использовать ImportDoctor, но я не могу заставить его работать.

...