SOAP input/output messages missing `Header` element
When generating SOAP messages from a WSDL, the Envelope for input and output defines only a Body and no Header.
Envelope specification: https://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383494
A SOAP message is an XML document that consists of a mandatory SOAP envelope, an optional SOAP header, and a mandatory SOAP body.
A generated SOAP message now looks like:
@dataclass
class SomeOperationInput:
class Meta:
name = "Envelope"
namespace = "http://schemas.xmlsoap.org/soap/envelope/"
body: Optional["SomeOperationInput.Body"] = field(
default=None,
metadata={
"name": "Body",
"type": "Element",
},
)
@dataclass
class Body:
-----8<-------
The Header element is missing here.
As a result, I am unable to parse incoming SOAP requests that I send from SOAP UI. The parser complains about the now unexpected Header element.
xsdata.exceptions.ParserError: Unknown property {http://schemas.xmlsoap.org/soap/envelope/}Envelope:{http://schemas.xmlsoap.org/soap/envelope/}Header
with the request message structure looking like:
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:v20="http://www.reggefiber.nl/schemas/odfaccess/order/client/v20140102"
xmlns:v201="http://www.exmaple.com/soap">
<soapenv:Header/>
<soapenv:Body>
<v20:MyRequest>
<!-- -----8<----- -->
</v20:MyRequest>
</soapenv:Body>
</soapenv:Envelope>
Work-around
I currently work around this issue, by removing the Header from the request body, before passing it on to the xsdata parser. I use the following code for this:
from lxml import etree
def strip_header_from_envelope(request_xml: bytes) -> bytes:
tree = etree.fromstring(request_xml)
headers = tree.xpath(
"/soapenv:Envelope/soapenv:Header",
namespaces={"soapenv": "http://schemas.xmlsoap.org/soap/envelope/"}
)
if headers:
envelope = headers[0].getparent()
envelope.remove(headers[0])
request_xml_without_header = etree.tostring(tree, encoding="utf-8")
return request_xml_without_header
This is not super efficient, since the XML gets deserialzed and serialzed to handle the removal of the Header from the request XML data.
You can disable failures on unknown properties @mmakaay
https://xsdata.readthedocs.io/en/latest/data_binding/basics/#fail_on_unknown_properties
Shouldn't the wsdl include information about the header then, I am not sure what we should generate there...
An optional empty Header would do I think, since that is what SOAP UI seems to find valid.
For my use case, I am fine with disabling failures here. Thanks for the hint, and feel free to close this issue.