PHP Soap сложные параметры с повторяющимися ключами - PullRequest
0 голосов

Мне нужно сгенерировать следующий 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>

Я использую PHP 7.1.17 и SoapClient.

Я не могу передать параметры SoapClient, так как клавиша instrument повторяетсяи связанный массив PHP не может иметь один и тот же ключ дважды.Я пытался создать объект и установить instrument свойства как SoapVar, но он генерирует неправильный XML.Вот код и результат:

$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/> остается пустым в результирующем 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>

Как передать параметры в SoapClient, чтобы сгенерировать XML с повторяющимися ключами instrument

1 Ответ

0 голосов

Я решил это.Оказывается, когда вы передаете упорядоченный массив (не ассоциативный) в качестве свойства объекта, так как многие XML-узлы генерируются с использованием имени этого свойства, как число элементов в массиве.Поэтому вместо создания SoapVar объектов и помещения их в массив instruments[] я просто назначил массив инструментов для instruments как свойство instrument:

$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;

Я строю инструменты в foreachпетля.Кстати преобразование массива в объект вместо сборки stdClass также работает нормально:

$options->instruments->instrument[] = (object)[
    'id' => 'US0000000001',
    'type' => 'ISIN',
    'yellowkey' => 'Equity'
]
...