So there are few issues with your code. For this to work, you need to use the SoapClient in WSDL mode ($client = new \SoapClient($wsdl);
, which you are doing). Next below is wrong
$claim = [...];
$claim = new \SoapVar($claim, SOAP_ENC_OBJECT, null, null, 'claim claimId="' . ($key+1) . '"');
$claims['claim claimId="'.($key+1).'"'] = $claim;
You don't add attributes using 'claim claimId="' . ($key+1) . '"'
.
Now what you need is to use a classmap
. Below is a sample python flask app I created to show the WSDL
from flask import Flask
app = Flask(__name__)
@app.route("/ICalculator",methods=['get', 'post'])
def reply():
return "<xmldata />"
@app.route("/app.wsdl")
def send():
return """<wsdl:definitions
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract"
xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl"
xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
xmlns:wsa10="http://www.w3.org/2005/08/addressing"
xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" targetNamespace="http://localhost:5001"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<xsd:schema targetNamespace="http://localhost:5001" elementFormDefault="qualified" >
<xsd:element name="Claim">
<xsd:complexType>
<xsd:sequence>
<xsd:element minOccurs="0" name="a" type="xsd:int" />
<xsd:element minOccurs="0" name="b" type="xsd:int" />
</xsd:sequence>
<xsd:attribute name="claimId" type="xsd:nonNegativeInteger" use="required" />
</xsd:complexType>
</xsd:element>
<xsd:element name="AddResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element minOccurs="0" name="result" type="xsd:int" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</wsdl:types>
<wsdl:message name="ICalculator_Add_InputMessage">
<wsdl:part name="parameters" element="tns:Add" />
</wsdl:message>
<wsdl:message name="ICalculator_Add_OutputMessage">
<wsdl:part name="parameters" element="tns:AddResponse" />
</wsdl:message>
<wsdl:portType name="ICalculator">
<wsdl:operation name="Add">
<wsdl:input wsaw:Action="http://localhost:5001/ICalculator/Add" message="tns:ICalculator_Add_InputMessage" />
<wsdl:output wsaw:Action="http://localhost:5001/ICalculator/AddResponse" message="tns:ICalculator_Add_OutputMessage" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="DefaultBinding_ICalculator" type="tns:ICalculator">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="Add">
<soap:operation soapAction="http://localhost:5001/ICalculator/Add" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="CalculatorService">
<wsdl:port name="ICalculator" binding="tns:DefaultBinding_ICalculator">
<soap:address location="http://localhost:5001/ICalculator" /></wsdl:port>
</wsdl:service>
</wsdl:definitions>
""".replace(r"\r", "").replace(r"\n", "")
if __name__ == "__main__":
app.run(debug=True, host='0.0.0.0', port=5000)
Then ran the same using
python3 wsdl.py
And ran another socat
to view the traffic
socat -v TCP-LISTEN:5001,fork TCP:127.0.0.1:5000
Next I wrote a sample PHP code to show how classmap
works
<?php
class Claim {
public function __construct(Array $properties=array()){
foreach($properties as $key => $value){
$this->{$key} = $value;
}
}
}
$test = new Claim(array('claimId'=>10, 'a'=> 22, 'b'=> 33));
$claim=new SoapVar($test, SOAP_ENC_OBJECT);
$wsdl = "http://localhost:5001/app.wsdl";
$client = new SoapClient($wsdl, array(
'trace' => 1,
'encoding' => 'UTF-8',
'soap_version' => SOAP_1_1,
'classmap' => array('Claim' => 'Claim')
));
$client->add($claim);
And the resultant xml
is
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://localhost:5001" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><SOAP-ENV:Body><parameters claimId="10" xsi:type="ns1:Claim"><ns1:a>22</ns1:a><ns1:b>33</ns1:b></parameters></SOAP-ENV:Body></SOAP-ENV:Envelope>

References:
PHP soap request with an element attribute and child elements
PHP SoapVar Object Attribute?
Adding attributes to the actual function tag in PHP soapCall
How do I add additional attributes to XML Elements with the SoapClient Class in PHP
php SoapVar not setting attributes
Getting the XML as string for a SoapVar variable - without a webservice (locally)?
Getting the XML as string for a SoapVar variable - without a webservice (locally)?
http://fvue.nl/wiki/Php:_Soap:_How_to_add_attribute_to_SoapVar
https://forums.phpfreaks.com/topic/137357-solved-php-soap-client-node-attributes/
http://eosrei.net/articles/2012/01/php-soap-xml-attributes-namespaces-xmlwriter