Как разобрать SOAP-ответ без SoapClient

Я провел последние несколько дней, пытаясь разобрать ответ SOAP, но я не могу заставить его работать. Я хотел бы иметь возможность получить все объекты «oproduct».

EDIT: Я делаю это так, вместо использования встроенного клиента SOAP, потому что мне нужно выполнять параллельные запросы с помощью multi_curl.

Вот мой код:

$xml = simplexml_load_string($response); $xml->registerXPathNamespace('soap-env', 'http://schemas.xmlsoap.org/soap/envelope/'); foreach ($xml->xpath('//oproduct') as $item) { // do something } 

Вот ответ:

 <soap-env:envelope xmlns:ns1="http://v3.core.com.productserve.com/" xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"> <soap-env:body> <ns1:getproductlistresponse> <oproduct> <iid>113133802</iid> <icategoryid>270</icategoryid> <imerchantid>1547</imerchantid> <iadult>0</iadult> <sname>The Ashes / 5th Test - England v Australia - Day 1</sname> <sawdeeplink>http://www.awin1.com/pclick.php?p=113133802&amp;a=111402&amp;m=1547&amp;platform=cs</sawdeeplink> <sawthumburl>http://img.ruphp.com/soap/113133802.gif</sawthumburl> <fprice>119.99</fprice> </oproduct> <oproduct> <iid>113133791</iid> <icategoryid>270</icategoryid> <imerchantid>1547</imerchantid> <iadult>0</iadult> <sname>The Ashes / 1st Test - England v Australia - Day 1</sname> <sawdeeplink>http://www.awin1.com/pclick.php?p=113133791&amp;a=111402&amp;m=1547&amp;platform=cs</sawdeeplink> <sawthumburl>http://img.ruphp.com/soap/113133791.gif</sawthumburl> <fprice>69.99</fprice> </oproduct> <oproduct> <iid>51155349</iid> <icategoryid>428</icategoryid> <imerchantid>513</imerchantid> <iadult>0</iadult> <sname>Rapitest DTM 118 Damp Test Meter</sname> <sawdeeplink>http://www.awin1.com/pclick.php?p=51155349&amp;a=111402&amp;m=513&amp;platform=cs</sawdeeplink> <sawthumburl>http://img.ruphp.com/soap/51155349.gif</sawthumburl> <fprice>18.35</fprice> </oproduct> <oproduct> <iid>187948</iid> <icategoryid>474</icategoryid> <imerchantid>496</imerchantid> <iadult>0</iadult> <sname>Rapitest Dm 10 Electrical Multimeter</sname> <sawdeeplink>http://www.awin1.com/pclick.php?p=187948&amp;a=111402&amp;m=496&amp;platform=cs</sawdeeplink> <sawthumburl>http://img.ruphp.com/soap/187948.jpg</sawthumburl> <fprice>26.71</fprice> </oproduct> <oproduct> <iid>51155353</iid> <icategoryid>428</icategoryid> <imerchantid>513</imerchantid> <iadult>0</iadult> <sname>Rapitest DM 10 Electrical Multimeter</sname> <sawdeeplink>http://www.awin1.com/pclick.php?p=51155353&amp;a=111402&amp;m=513&amp;platform=cs</sawdeeplink> <sawthumburl>http://img.ruphp.com/soap/51155353.gif</sawthumburl> <fprice>22.7</fprice> </oproduct> <oproduct> <iid>49152850</iid> <icategoryid>474</icategoryid> <imerchantid>1366</imerchantid> <iadult>0</iadult> <sname>Testboy Profi LED Plus</sname> <sawdeeplink>http://www.awin1.com/pclick.php?p=49152850&amp;a=111402&amp;m=1366&amp;platform=cs</sawdeeplink> <sawthumburl>http://img.ruphp.com/soap/49152850.jpg</sawthumburl> <fprice>44.99</fprice> </oproduct> <oproduct> <iid>51155350</iid> <icategoryid>428</icategoryid> <imerchantid>513</imerchantid> <iadult>0</iadult> <sname>Rapitest ETP 116 Electrical Test Probe</sname> <sawdeeplink>http://www.awin1.com/pclick.php?p=51155350&amp;a=111402&amp;m=513&amp;platform=cs</sawdeeplink> <sawthumburl>http://img.ruphp.com/soap/51155350.gif</sawthumburl> <fprice>17.55</fprice> </oproduct> <oproduct> <iid>51155351</iid> <icategoryid>428</icategoryid> <imerchantid>513</imerchantid> <iadult>0</iadult> <sname>Rapitest ET 111 Electrical Test Meter</sname> <sawdeeplink>http://www.awin1.com/pclick.php?p=51155351&amp;a=111402&amp;m=513&amp;platform=cs</sawdeeplink> <sawthumburl>http://img.ruphp.com/soap/51155351.gif</sawthumburl> <fprice>13.55</fprice> </oproduct> <oproduct> <iid>72326941</iid> <icategoryid>474</icategoryid> <imerchantid>496</imerchantid> <iadult>0</iadult> <sname>Rapitest Etp 116 Electrical Test Probe</sname> <sawdeeplink>http://www.awin1.com/pclick.php?p=72326941&amp;a=111402&amp;m=496&amp;platform=cs</sawdeeplink> <sawthumburl>http://img.ruphp.com/soap/72326941.jpg</sawthumburl> <fprice>20.66</fprice> </oproduct> <oproduct> <iid>49338340</iid> <icategoryid>206</icategoryid> <imerchantid>80</imerchantid> <iadult>0</iadult> <sname>Ladies Protest Zekke Jacket True Black</sname> <sawdeeplink>http://www.awin1.com/pclick.php?p=49338340&amp;a=111402&amp;m=80&amp;platform=cs</sawdeeplink> <sawthumburl>http://img.ruphp.com/soap/49338340.jpg</sawthumburl> <fprice>54.99</fprice> </oproduct> <itotalcount>6350</itotalcount> </ns1:getproductlistresponse> </soap-env:body> </soap-env:envelope> 

Не могли бы вы уточнить, какую версию PHP вы используете (4 или 5)? Также есть особая причина, по которой вы не хотите / не можете использовать расширение SOAP PHP 5? Знание этой информации должно помочь нам дать вам лучший ответ.

Причина, по которой приведенный выше пример кода не работает, заключается в том, что вы ищете неправильное пространство имен для узлов oproduct. Хотя корневой узел содержится в пространстве имен SOAP, oproduct находятся под пространством имен «http://v3.core.com.productserve.com/&#xBB;. Вам также нужно использовать псевдоним пространства имен в запросе XPath. Попробуйте это, хотя я его не тестировал:

 $xml = simplexml_load_string($response); $xml->registerXPathNamespace('ns', 'http://v3.core.com.productserve.com/'); foreach ($xml->xpath('//ns:oproduct') as $item) { // do something } 

Надеюсь, это решит вашу непосредственную проблему.

EDIT Спасибо за разъяснение. Опять же, непроверенный, но, возможно, это сработает:

 $xml = simplexml_load_string($response); $xml->registerXPathNamespace('soapenv', 'http://schemas.xmlsoap.org/soap/envelope/'); $xml->registerXPathNamespace('ns', 'http://v3.core.com.productserve.com/'); foreach ($xml->xpath('/soapenv:envelope/soapenv:body/ns:getproductlistresponse/ns:oproduct') as $item) { // do something } 

Возможно, вам нужно перейти от корневого узла к мылу Env: body к узлам oproduct в запросе. Надеюсь, это сработает.

Дальнейшее редактирование: я думаю, что я только что взломал это. Попробуйте следующий код:

 $xml = simplexml_load_string($response); $ns = $xml->getNamespaces(true); $soap = $xml->children($ns['soap-env']); $getproductlistresponse = $soap->body->children($ns['ns1']); foreach ($getproductlistresponse->children() as $item) { //This example just accesses the iid node but the others are all available. echo (string) $item->iid . '<br />'; } 

Не самый красивый код, но он работает. Я надеялся заставить это работать с запросом XPath, но это было за пределами моих рудиментарных знаний о XPath. Возможно, кто-то еще может опубликовать ответ с помощью XPath?

PHP поставляется с SOAP-клиентом, который должен сделать это, поэтому вам не нужно вручную разбирать SOAP XML. См. Здесь: http://php.net/manual/en/book.soap.php

Изменить. Для ясности клиент SOAP не является частью PHP, а является расширением.