I need to generate the following XML
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://services.bloomberg.com/datalicense/dlws/ps/20071001">
<SOAP-ENV:Body>
<ns1:submitGetHistoryRequest>
<ns1:headers>
<ns1:daterange>
<ns1:period>
<ns1:start>2018-05-08</ns1:start>
<ns1:end>2018-05-08</ns1:end>
</ns1:period>
</ns1:daterange>
</ns1:headers>
<ns1:fields>
<ns1:field>PX_LAST</ns1:field>
</ns1:fields>
<ns1:instruments>
<ns1:instrument>
<ns1:id>US0000000002</ns1:id>
<ns1:yellowkey>Equity</ns1:yellowkey>
<ns1:type>ISIN</ns1:type>
</ns1:instrument>
<ns1:instrument>
<ns1:id>US0000000001</ns1:id>
<ns1:yellowkey>Equity</ns1:yellowkey>
<ns1:type>ISIN</ns1:type>
</ns1:instrument>
</ns1:instruments>
</ns1:submitGetHistoryRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
I use PHP 7.1.17 and SoapClient.
I can not pass options to SoapClient, as the instrument
key is repeated and PHP's associated array can not have same key twice. I tried constructing object and setting instrument
properties as SoapVar
, but it generates incorrect XML. Here is code and result:
$options = new \stdClass();
$options->headers = new \stdClass();
$options->headers->daterange = new \stdClass();
$options->headers->daterange->period = new \stdClass();
$options->headers->daterange->period->start = '2018-05-08';
$options->headers->daterange->period->end = '2018-05-08';
$options->fields = new \stdClass();
$options->fields->field = 'PX_LAST';
//first instrument
$instrument = new \stdClass();
$instrument->id = 'US0000000002';
$instrument->type = 'ISIN';
$instrument->yellowkey = 'Equity';
$options->instruments[] = new \SoapVar(
$instrument,
SOAP_ENC_OBJECT,
'stdClass',
"http://soapinterop.org/xsd",
"instrument"
);
//second instrument
$instrument = new \stdClass();
$instrument->id = 'US0000000001';
$instrument->type = 'ISIN';
$instrument->yellowkey = 'Equity';
$options->instruments[] = new \SoapVar(
$instrument,
SOAP_ENC_OBJECT,
'stdClass',
"http://soapinterop.org/xsd",
"instrument"
);
<ns1:instruments/>
remains empty in resulting XML:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://services.bloomberg.com/datalicense/dlws/ps/20071001">
<SOAP-ENV:Body>
<ns1:submitGetHistoryRequest>
<ns1:headers>
<ns1:daterange>
<ns1:period>
<ns1:start>2018-05-08</ns1:start>
<ns1:end>2018-05-08</ns1:end>
</ns1:period>
</ns1:daterange>
</ns1:headers>
<ns1:fields>
<ns1:field>PX_LAST</ns1:field>
</ns1:fields>
<ns1:instruments/>
</ns1:submitGetHistoryRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
How can I pass options to SoapClient, to generate XML with repeated instrument
keys?
I solved this. Turns out when you pass an ordered array (not associative one) as object's property, as many XML nodes are generated using that property's name, as number of elements in the array. So instead of building SoapVar
objects and putting them into instruments[]
array, I just assigned array of instruments to instruments
as instrument
property:
$options->instruments = new \stdClass();
//first instrument
$instrument = new \stdClass();
$instrument->id = 'US0000000002';
$instrument->type = 'ISIN';
$instrument->yellowkey = 'Equity';
$options->instruments->instrument[] = $instrument;
//second instrument
$instrument = new \stdClass();
$instrument->id = 'US0000000001';
$instrument->type = 'ISIN';
$instrument->yellowkey = 'Equity';
$options->instruments->instrument[] = $instrument;
I build instruments in a foreach
loop. Btw converting array to object instead of building stdClass
also works fine:
$options->instruments->instrument[] = (object)[
'id' => 'US0000000001',
'type' => 'ISIN',
'yellowkey' => 'Equity'
]