Suds Generates Empty Elements; How To Remove Them?
Solution 1:
You can use a plugin to modify the XML before is sent to the server (my answer is based on Ronald Smith's solution):
from suds.plugin import MessagePlugin
from suds.client import Client
import re
classMyPlugin(MessagePlugin):
defsending(self, context):
context.envelope = re.sub('\s+<.*?/>', '', context.envelope)
client = Client(URL_WSDL, plugins=[MyPlugin()])
Citing the documentation:
The MessagePlugin currently has (5) hooks :: (...) sending() Provides the plugin with the opportunity to inspect/modify the message text before it is sent.
Basically Suds will call sending
before the XML is sent, so you can modify the generated XML (contained in context.envelope
). You have to pass the plugin class MyPlugin to the Client
constructor for this to work.
Edit
Another way is to use marshalled
to modify the XML structure, removing the empty elements (untested code):
classMyPlugin(MessagePlugin):defmarshalled(self, context):
#remove empty tags inside the Body element#context.envelope[0] is the SOAP-ENV:Header element
context.envelope[1].prune()
Solution 2:
There's an even easier way - no need for any Reg Ex or exciting iterators ;)
First, define the plugin:
classPrunePlugin(MessagePlugin):defmarshalled(self, context):
context.envelope = context.envelope.prune()
Then use it when creating the client:
client = Client(url, plugins=[PrunePlugin()])
The prune() method will remove any empty nodes, as documented here: http://jortel.fedorapeople.org/suds/doc/suds.sax.element.Element-class.html
Solution 3:
The Suds factory method generates a regular Python object with regular python attributes that map to the WSDL type definition.
You can use the 'del' builtin function to remove attributes.
>>> order_details = c.factory.create('ns2:OrderDetails')
>>> order_details
(OrderDetails){
Amount = None
CurrencyCode = None
OrderChannelType =
(OrderChannelType){
value = None
}
OrderDeliveryType =
(OrderDeliveryType){
value = None
}
OrderLines =
(ArrayOfOrderLine){
OrderLine[] = <empty>
}
OrderNo = None
TotalOrderValue = None
}
>>> del order_details.OrderLines
>>> del order_details.OrderDeliveryType
>>> del order_details.OrderChannelType
>>> order_details
(OrderDetails){
Amount = None
CurrencyCode = None
OrderNo = None
TotalOrderValue = None
}
Solution 4:
You can filter the empty elements out with a regular expression.
Assuming your XML data is in the string xmltext
;
importrefilteredtext= re.sub('\s+<.*?/>', '', xmltext)
Solution 5:
What do you think of the following MonkeyPatch to skip complex types with a None
value?
from suds.mx.literal import Typed
old_skip = Typed.skip
defnew_skip(self, content):
x = old_skip(self, content)
ifnot x andgetattr(content.value, 'value', False) isNone:
x = Truereturn x
Typed.skip = new_skip
Post a Comment for "Suds Generates Empty Elements; How To Remove Them?"