Search code examples
pythonxmlsoapsuds

How to convert suds object to xml string


This is a duplicate to this question: How to convert suds object to xml
But the question has not been answered: "totxt" is not an attribute on the Client class. Unfortunately I lack of reputation to add comments.
So I ask again: Is there a way to convert a suds object to its xml?

I ask this because I already have a system that consumes wsdl files and sends data to a webservice. But now the customers want to alternatively store the XML as files (to import them later manually). So all I need are 2 methods for writing data: One writes to a webservice (implemented and tested), the other (not implemented yet) writes to files. If only I could make something like this:
xml_as_string = My_suds_object.to_xml()

The following code is just an example and does not run. And it's not elegant. Doesn't matter. I hope you get the idea what I want to achieve: I have the function "write_customer_obj_webservice" that works. Now I want to write the function "write_customer_obj_xml_file".

import suds

def get_customer_obj():
    wsdl_url = r'file:C:/somepathhere/Customer.wsdl'
    service_url = r'http://someiphere/Customer'
    c = suds.client.Client(wsdl_url, location=service_url)
    customer = c.factory.create("ns0:CustomerType")
    return customer

def write_customer_obj_webservice(customer):
    wsdl_url = r'file:C:/somepathhere/Customer.wsdl'
    service_url = r'http://someiphere/Customer'
    c = suds.client.Client(wsdl_url, location=service_url)
    response = c.service.save(someparameters, None, None, customer)
    return response

def write_customer_obj_xml_file(customer):
    output_filename = r'C\temp\testxml'
    # The following line is the problem. "to_xml" does not exist and I can't find a way to do it.
    xml = customer.to_xml()
    fo = open(output_filename, 'a')
    try:
        fo.write(xml)
    except:
        raise
    else:
        response = 'All ok'
    finally:
        fo.close()
    return response

# Get the customer object always from the wsdl.
customer = get_customer_obj()
# Since customer is an object, setting it's attributes is very easy. There are very complex objects in this system.
customer.name = "Doe J."
customer.age = 42
# Write the new customer to a webservice or store it in a file for later proccessing
if later_processing:
    response = write_customer_obj_xml_file(customer)
else:
    response = write_customer_obj_webservice(customer)

Solution

  • I found a way that works for me. The trick is to create the Client with the option "nosend=True".
    In the documentation it says:

    nosend - Create the soap envelope but don't send. When specified, method invocation returns a RequestContext instead of sending it.

    The RequestContext object has the attribute envelope. This is the XML as string.
    Some pseudo code to illustrate:

    c = suds.client.Client(url, nosend=True)
    customer = c.factory.create("ns0:CustomerType")
    customer.name = "Doe J."
    customer.age = 42
    response = c.service.save(someparameters, None, None, customer)
    print response.envelope # This prints the XML string that would have been sent.