I am generating an XML with the ZEEP library for a SOAP API.
My problem is that according to the documentation I need to add
xmlns:tem="http://tempuri.org/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
in the SOAP-ENV tag because if not I get an error when making the call.
I would like to know how I can add these attributes to it.
It's much more complicated than it should be. After thinking about it for a long time I have come to the following solution, which is not entirely satisfactory but I hope it will help you.
The problem is that, unless you want to directly manipulate the string representation of the XML (which I don't think is recommended), what we have is the API
lxml
for modifying the elements of the XML tree. And using that API you can't add attributes to an element whose attribute name contains a colon, because that syntax is reserved for namespaces namespaces .Actually, the attributes you need to add are defining two new namespaces , the first called
tem
and the second calledxsi
. Your document is supposed to later use those prefixes as part of other attributes or elements, with things likexsi:type
eg etc.So it seems that what we should do is use
lxml
to add two new namespaces to the root element. Butlxml
it does not make it easy, since:For one thing, it only adds namespaces if you're actually using them in some other attribute or child of the element. That forces me to create a couple of "fake" attributes that use those namespaces. For example,
tem:nil
andxmlns:nil
, to put something. I'm not sure if those attribute names are valid within those namespaces , so I say that I hope it doesn't give you problems. I also have to give a value to those attributes. Since they are just a "trick" to force tolxml
include them, I don't know what value to give them and have opted for the empty string.lxml
in principle, it decides for itself which prefixes to use for the namespaces you add, based on the URL they point to. In your case, the urlhttp://www.w3.org/2001/XMLSchema-instance
is "well known" bylxml
and prefixedxsi
with , which matches what you need. On the other hand, the urlhttp://tempuri.org/
is not known to him and he assigns it as a prefixns0
, instead oftem
what you need. To change that you have to register that url as a new namespace , usingetree.register_namespace()
.All this is exemplified by the following code:
As you can see, the result is almost what you need, except that the
tem:nil
and attributes are left overxsi:nil
, but I hope those don't cause you problems.All this (except loading the example file, since in your case the document arrives as a parameter) you would have to do it within the
egress
Zeep plugin method, of which you have an example hereI have managed to find a way to add my own prefixes manually, in this case because I was getting the prefixes that were in the wsdl wrong.
With the ZEEP library we load the wsdl into an object. This object has the "set_ns_prefix" function, which needs 2 values, the prefix and the url. Once loaded we can print the prefixes using the "prefix" variable of that object.