8

I think what I am trying to do is pretty much like github issue in zeep repo --- but sadly there is no response to this issue yet. I researched suds and installed and tried -- did not even get sending parameter to work and thought zeep seems better maintained?

Edit 1: For sure I am not talking about this

Junchao Gu
  • 1,815
  • 6
  • 27
  • 43

2 Answers2

9

You can use a Plugin for editing the xml as a plain string. I used this plugin for keeping the characters '<' and '>' in a CDATA element.

from xml import etree
from zeep import Plugin

class my_plugin(Plugin):

    def egress(self, envelope, http_headers, operation, binding_options):
        xml_string = etree.ElementTree.tostring(envelope)
        xml_string = xml_string.replace("&lt;", "<")
        xml_string = xml_string.replace("&gt;", ">")
        parser = etree.ElementTree.XMLParser(strip_cdata=False)
        new_envelope = etree.ElementTree.XML(xml_string, parser=parser)
        return new_envelope, http_headers

Then just import the plugin on the client:

client = Client(wsdl='url', transport=transport, plugins=[my_plugin()])

Take a look at the docs: http://docs.python-zeep.org/en/master/plugins.html

AndyTheEntity
  • 3,396
  • 1
  • 22
  • 19
David Ortiz
  • 997
  • 1
  • 14
  • 22
  • 1
    Thanks for sharing. Though I think it should be a feature to send raw message or send xml data. – Junchao Gu Mar 16 '18 at 00:47
  • This works on Python 3 by using `xmlString = etree.tostring(envelope, encoding='unicode')`. Additionally, you might also need to `xmlString = xmlString.replace("&", "&")` if you have any ampersands. – Martin Burch Jul 23 '19 at 21:52
  • py3: etree.tostring, etree.XMLParser, etree.XML – mirek Dec 22 '22 at 15:18
2

On Python 3.9, @David Ortiz answer didn't work for me, maybe something has changed. The etree_to_string was failing to convert the XML to string.

What worked for me, instead of a plugin, I created a custom transport, that replaced the stripped tags with the correct characters, just like David's code, before the post was sent.

import zeep
from zeep.transports import Transport
from xml.etree import ElementTree

class CustomTransport(Transport):  
    def post_xml(self, address, envelope, headers):  
        message = ElementTree.tostring(envelope, encoding="unicode")  
        message = message.replace("&lt;", "<")  
        message = message.replace("&gt;", ">")  
        return self.post(address, message, headers)  


client = zeep.Client('wsdl_url', transport=CustomTransport())
Jeff Olivr
  • 21
  • 2