Subject: | Value of root element in SOAP Body ignored |
Date: | Tue, 26 Aug 2014 14:01:58 +0100 |
To: | <bug-SOAP-Lite [...] rt.cpan.org> |
From: | Oliver Lightfoot <oliver.lightfoot [...] retaildata.co.uk> |
I have found a bug in SOAP::Lite.
SOAP::Lite version: 1.11.
perl version: 5.10.
OS: Debian Linux v6.0 (Squeeze)
The bug occurs when you set a value for the root element in SOAP Body
and do not have any child elements. Rather than using the value set on
the root SOAP::Data object it sets the value to undef which results in
the root element having the xsi:nil="true" attribute set.
The following code replicates this bug:
my $client = SOAP::Lite
->proxy('http://localhost:8080', timeout => 360)
->on_action(sub {return ""});
my $body =
SOAP::Data->name("ns1:SendData")->value('SomeTestData11212')->type("");
$client->call($body);
This results in the following XML:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://www.foo.com/bar/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<ns1:SendData xsi:nil="true" />
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
As you can see the SendDate tag has been serialized as nil, however I
propose it should actually be:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://www.foo.com/bar/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<ns1:SendData>SomeTestData11212</ns1:SendData>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Now the SendData tag has been serialized with the value set in the code
example. I have tried to find out if this is considered valid SOAP XML
and can fined nothing to suggest it is, so it seems to me that this is a
valid expectation? I am working with a 3rd party SOAP server and this is
certainly what they expect.
I have found the code responsible for this behaviour in Lite.pm, line
1640, a copy is below:
$body->set_value($parameters ? \$parameters :
SOAP::Utils::encode_data()) if $body;
The problem with this code is it will always overwrite the body value,
ideally the code should check for a body value and use this but only if
there are no other parameters, which obvously would be embedded as child
elements and thus replace any root value?
In order to change the behaviour so it will not ignore the root element
value I change the code to:
if ($body && !defined($body->value()) || defined($parameters)) {
$body->set_value($parameters ? \$parameters :
SOAP::Utils::encode_data());
}
I hope that you seriously consider adopting this change, it seems like a
valid use case, however I am sure you are much better placed to decide
this. If you could let me know your decision one way or another that
would be greatly appreciated.
Thank you for your time.
Best regards,
--
Oliver Lightfoot
Senior Developer
The Retail Data Partnership Ltd
Brewery House
4 Scotgate
Stamford PE9 2YB
Telephone 01780 480562