Hi Group,
I built a gSoap 2.7.11 Web services client in C++ on AIX and have got
it talking to the remote service. The service is sending back an
array of objects to my client but the client is unable to decode it.
The client seems to be having a problem with the "item" tag element
that is used to wrap the sequence of array objects.
The SOAP call returns a SOAP_OK - no exception or error returned to
the client. The returned XML looks good except for the <item/> tag
wrapping each array object (which gSoap doesn't like).
Section 10.11.2 in the gSoap documentation talks about removing the
namespace part of the array wrapper class so I made this change in
the soapcpp2 input file but it has made no difference.
Would really appreciate some help on this.
Thanks a lot,
Paul.
Paulc - The returned XML response is valid according to the schema:
<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http//www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header/>
<soapenv:Body>
<accountValuationResponse xsi:type="soapenc:Array" soapenc:arrayType="ns-1550380365:AccountValuationSummary[1]" xmlns:ns-1550380365="http://xmlns.fid-intl.com/smt/valuation/valuation/1.0" xmlns="http://xmlns.fid-intl.com/smt/valuation/valuationService/1.0">
<item xmlns=""> <currencyCode>GBP</currencyCode>
<productGroupCode>CMA </productGroupCode>
<netValue>500.00</netValue>
<accountType>M</accountType>
<policyNumber xsi:nil="true"/>
<designation xsi:nil="true"/>
</item>
</accountValuationResponse>
</soapenv:Body>
</soapenv:Envelope>
Paulc - Heres the relevant part of the gsoap decode XML log. I’ve highlighted where it starts going wrong.
Push OK ('' matches 'ns3' in namespace table)
Tags and (default) namespaces match: 'xsi:type' 'xsi:type'
Tags and (default) namespaces match: 'soapenc:arrayType' 'SOAP-ENC:arrayType'
Tags and (default) namespaces match: 'accountValuationResponse' 'ns3:accountValuationResponse'
Begin element found (level=3) 'accountValuationResponse'='ns3:accountValuationRe sponse'
[b]Enter id='' type=9 loc=2ff09f38 size=16 level=0
stdsoap2.cpp(2747): malloc(21) = 20039bc8
Push namespace binding (level=3) '' ''
Push NOT OK: no match found for '' in namespace mapping table (added to stack anyway)
Unexpected element 'item' in input (level=3, 1)
IGNORING element 'item'
stdsoap2.cpp(8215): malloc(27) = 20039c08
stdsoap2.cpp(8269): malloc(256) = 20039c58
Tags and (default) namespaces match: 'xsi:nil' 'xsi:nil'
Unexpected element 'currencyCode' in input (level=4, 0)
IGNORING element 'currencyCode'
Unexpected element 'productGroupCode' in input (level=4, 1)
IGNORING element 'productGroupCode'
End element found (level=5) 'productGroupCode'=''
Paulc – heres the generated decode classes without the changes suggested in the gsoap manual.
(I tried renaming AccountValuationSummary to AccountValuationSummaryitem and changed _ns3__accountValuationResponse to accountValuationResponse in the input .h file to soapcpp2, but it still fails as above)
class SOAP_CMAC _ns3__accountValuationResponse
{
public:
int __sizeAccountValuationSummary;
class ns4__AccountValuationSummary **AccountValuationSummary;
struct soap *soap;
public:
virtual int soap_type() const { return 9; } /* = unique id SOAP_TYPE__ns3__accountValuationResponse */
virtual void soap_default(struct soap*);
virtual void soap_serialize(struct soap*) const;
......STD SOAP STUFF
_ns3__accountValuationResponse() : __sizeAccountValuationSummary(0), AccountValuationSummary(NULL), soap(NULL) { }
virtual ~_ns3__accountValuationResponse() { }
};
Paulc – Heres the structure itself
class SOAP_CMAC ns4__AccountValuationSummary
{
public:
char *currencyCode; /* optional element of type xsd:string */
char *productGroupCode; /* optional element of type xsd:string */
char *netValue; /* optional element of type xsd:decimal */
char *accountType; /* optional element of type xsd:string */
ETC....
char *designation; /* optional element of type xsd:string */
struct soap *soap; /* transient */
public:
virtual int soap_type() const { return 15; } /* = unique id SOAP_TYPE_ns4__AccountValuationSummary */
virtual void soap_default(struct soap*);
virtual void soap_serialize(struct soap*) const;
virtual int soap_put(struct soap*, const char*, const char*) const;
virtual int soap_out(struct soap*, const char*, int, const char*) const;
virtual void *soap_get(struct soap*, const char*, const char*);
virtual void *soap_in(struct soap*, const char*, const char*);
ns4__AccountValuationSummary() : currencyCode(NULL), productGroupCode(NULL), netValue(NULL), accountType(NULL), policyNumber(NULL), primaryAccOwnerSurname(NULL), re
gisteredAccountNumber(NULL), primaryAccOwnerTitle(NULL), primaryAccOwnerFirstName(NULL), designation(NULL), soap(NULL) { }
virtual ~ns4__AccountValuationSummary() { }
};