Search code examples
pythonxmldjangosoapwsdl

Consume WSDL url with XML with escaped chars as argument


I am executing a method of a SOAP web service which receives 3 string arguments with suds library.

The first string argument should be an XML and the other 2 an username and password, this is my semi-working implementation.

from suds.client import Client
url = "http://www.jonima.com.mx:3014/sefacturapac/TimbradoService?wsdl"
client = Client(url)
client.service.timbrado(XML_AS_STRING_HERE, 'PRUEBA1', '12345678')

When the first parameter contains an escaped character (ampersand, quotes, apostrophe, less than, bigger than) method does not work because the server interprets the text as if it were unescaped. If doesn't contain any of those chars the method works great

XML example without ampersand works http://dl.dropbox.com/u/1990697/no_amp.xml

XML example with ampersand doesn't work http://dl.dropbox.com/u/1990697/with_amp.xml

Any idea how can I pass XML with escaped chars?

It doesn't have to rely on suds but in python. I am using python 2.6 (How ever it could be with 2.7 if required)

I am also using Django framework, don't know if that could be useful.


Extra Info:

  • I have no access to modify SOAP server
  • Customer support told me my xml are correct and that they work for them, so the error is in my implementation (or somewhere in suds?)

Solution

  • I think the suds library is the culprit here. When you send your escaped xml into suds as a parameter to the client.service.timbrado method it also escapes it. However, it sees that you have escaped the ampersand already like this:

    ...
    descripcion="EJE&MPLO"
    ...
    

    And it does not escape it further (although it should). You should run your escaped xml through xml.sax.saxutils.escape before passing it to client.service.timbrado.

    This should result in xml snippet above looking like this:

    ...
    descripcion="EJE&MPLO"
    ...
    

    When I run your code with the doubly-escaped xml, I receive the following result:

    <?xml version="1.0" ?>
    <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
        <S:Body>
            <ns2:timbradoResponse xmlns:ns2="http://sefactura.com">
                <return>
                    <status>401 - Fecha y hora de generación fuera de rango</status>
                </return>
            </ns2:timbradoResponse>
        </S:Body>
    </S:Envelope>
    

    It is an error regarding your data (date and time of generation out of range), not about the format of the xml.