Andrea Bisello
Andrea Bisello

Reputation: 1215

python 3 - zeep - soap - 'Element Value from namespace xxx cannot have child contents to be deserialized as an object'

i have this method on my wsdl

<xs:element name="createDocument">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="repositoryId" nillable="true" type="xs:string"/>
<xs:element xmlns:q7="http://schemas.microsoft.com/2003/10/Serialization/Arrays" minOccurs="0" name="properties" nillable="true" type="q7:ArrayOfKeyValueOfstringanyType"/>
<xs:element xmlns:q8="http://docs.oasis-open.org/ns/cmis/core/200908/" minOccurs="0" name="contentStream" nillable="true" type="q8:ContentStream"/>
<xs:element xmlns:q9="http://docs.oasis-open.org/ns/cmis/core/200908/" minOccurs="0" name="versioningState" type="q9:VersioningState"/>
<xs:element xmlns:q10="http://schemas.microsoft.com/2003/10/Serialization/Arrays" minOccurs="0" name="policies" nillable="true" type="q10:ArrayOfstring"/>
</xs:sequence>
</xs:complexType>
</xs:element>

i need to call with python3 zeep library.

this is what i wrote


def test_createDocument():
    c_stream = file_to_b64bytes("assets/pdv/packagePdV.zip")
    c_length = len(c_stream)

    answer = client.service.createDocument(
        repositoryId="1",
        properties=[
            {
                "KeyValueOfstringanyType": {
                    "Key": "PdV_VerificaFirmaFiles",
                    "Value": False
                }
            },
            {
                "KeyValueOfstringanyType": {
                    "Key": "Firma_OggettiProduttore",
                    "Value": False
                }
            }

        ],
        contentStream={
            "filename": "packagePdV.zip",
            "length": c_length,
            "stream": c_stream
        }
    )

    print(answer)

but i got an exception

zeep.exceptions.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.

any suggestion?

Upvotes: 1

Views: 1125

Answers (2)

A_E
A_E

Reputation: 195

I faced the same problem but didn't want to leave Zeep.

After a lot of debugging and comparing the XML produced by Zeep by the one needed by the webservice I came up with the idea that Zeep wasn't specifying the data type "boolean" in the produced XML.

This can be done specifying 'Value': xsd.AnyObject(xsd.Boolean(), False) as the value for PdV_VerificaFirmaFiles.

So, finally, this code worked for me:

from zeep import xsd
....
soap_response = soap_client.service.createDocument(
            repositoryId=1,
            properties=[{
                'KeyValueOfstringanyType': {'Key': 'PdV_VerificaFirmaFiles',
                                            'Value': xsd.AnyObject(xsd.Boolean(), False)}
            }],
            contentStream={
                'filename': 'PdVDocumento.zip',
                'length': zip_size,
                'stream': zip_file_contents
            }
        )

Upvotes: 2

Andrea Bisello
Andrea Bisello

Reputation: 1215

to solve the problem, i changed the library from zeep to https://suds-py3.readthedocs.io/en/latest/ because it permits to change the xml message before sending through a plugin.

i also tried using the doctor to add namespace without success,

this is the code

class FixTypes(MessagePlugin):
    def marshalled(self, context):
        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')

client = Client("", username="", password="", plugins=[FixTypes()])

Upvotes: 1

Related Questions