Анализ SOAP-ответа

Вызов веб-службы с моего контроллера:

$client = new \SoapClient("http://.../webservice/NAME_OF_PAGE.asmx?WSDL"); $result = $client->EstadoHabitacionesFechas(); 

Я получаю это:

 <xs:schema xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="NewDataSet"> <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:MainDataTable="TablaEstadoHabitacion" msdata:UseCurrentLocale="true"> <xs:complexType> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="TablaEstadoHabitacion"> <xs:complexType><xs:sequence> <xs:element name="IdHabitacion" type="xs:int" minOccurs="0"/> <xs:element name="FechaEntrada" type="xs:string" minOccurs="0"/> <xs:element name="FechaSalida" type="xs:string" minOccurs="0"/> </xs:sequence> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> </xs:element> </xs:schema> <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1"> <DocumentElement xmlns=""> <TablaEstadoHabitacion diffgr:id="TablaEstadoHabitacion1" msdata:rowOrder="0" diffgr:hasChanges="inserted"> <IdHabitacion>1</IdHabitacion> <FechaEntrada>23/05/2012</FechaEntrada> <FechaSalida>31/12/2012</FechaSalida> </TablaEstadoHabitacion> <TablaEstadoHabitacion diffgr:id="TablaEstadoHabitacion2" msdata:rowOrder="1" diffgr:hasChanges="inserted"> <IdHabitacion>2</IdHabitacion> <FechaEntrada>23/05/2012</FechaEntrada> <FechaSalida>29/06/2012</FechaSalida> </TablaEstadoHabitacion> <TablaEstadoHabitacion diffgr:id="TablaEstadoHabitacion3" msdata:rowOrder="2" diffgr:hasChanges="inserted"> <IdHabitacion>2</IdHabitacion> <FechaEntrada>29/06/2012</FechaEntrada> <FechaSalida>01/07/2012</FechaSalida> </TablaEstadoHabitacion> <TablaEstadoHabitacion diffgr:id="TablaEstadoHabitacion4" msdata:rowOrder="3" diffgr:hasChanges="inserted"> <IdHabitacion>3</IdHabitacion> <FechaEntrada>02/06/2012</FechaEntrada> <FechaSalida>03/06/2012</FechaSalida> </TablaEstadoHabitacion> <TablaEstadoHabitacion diffgr:id="TablaEstadoHabitacion5" msdata:rowOrder="4" diffgr:hasChanges="inserted"> <IdHabitacion>3</IdHabitacion> <FechaEntrada>29/06/2012</FechaEntrada> <FechaSalida>01/07/2012</FechaSalida> </TablaEstadoHabitacion> <TablaEstadoHabitacion diffgr:id="TablaEstadoHabitacion6" msdata:rowOrder="5" diffgr:hasChanges="inserted"> <IdHabitacion>4</IdHabitacion> <FechaEntrada>29/06/2012</FechaEntrada> <FechaSalida>01/07/2012</FechaSalida> </TablaEstadoHabitacion> <TablaEstadoHabitacion diffgr:id="TablaEstadoHabitacion7" msdata:rowOrder="6" diffgr:hasChanges="inserted"> <IdHabitacion>5</IdHabitacion> <FechaEntrada>02/06/2012</FechaEntrada> <FechaSalida>03/06/2012</FechaSalida> </TablaEstadoHabitacion> <TablaEstadoHabitacion diffgr:id="TablaEstadoHabitacion20" msdata:rowOrder="19" diffgr:hasChanges="inserted"> <IdHabitacion>10</IdHabitacion> <FechaEntrada>02/06/2012</FechaEntrada> <FechaSalida>03/06/2012</FechaSalida> </TablaEstadoHabitacion> </DocumentElement> </diffgr:diffgram> 

Как я могу разобрать эти данные и использовать их?

Вы не совсем поняли, что такое «использование», но вам явно нужна форма XML-анализа или поиска.

Например, попробуйте xml-загрузить эту строку и var_dump результат. Просто перечисление различных свойств должно показать вам возможности.

Позже вы можете попробовать поиск XPath и более продвинутые «трюки», чтобы ускорить работу.

  // Remove namespaces $xml = str_replace(array("diffgr:","msdata:"),'', $xml); // Wrap into root element to make it standard XML $xml = "<package>".$xml."</package>"; // Parse with SimpleXML - probably there're much better ways $data = simplexml_load_string($xml); $rooms = $data->package->diffgram->DocumentElement->TablaEstadoHabitacion; print "We have " . count($rooms) . " rooms: \n"; foreach($rooms as $i => $room) { print "Room {$i}: id={$room['id']} (official id: {$room->IdHabitacion}\n"; print "Entrada {$room->FechaEntrada}, salida {$room->FechaSalida}\n...\n"; } 

Есть несколько парсеров, которые вы можете использовать, это быстрый и грязный.

Подробнее см. Здесь .

Большие наборы данных

Примечание : для очень больших наборов данных XML я обнаружил, что foreach лучше .

И для больших наборов данных, где вам нужна только небольшая информация, и весь файл может не вписываться в доступную память, вы, вероятно, захотите использовать XMLParser или XMLReader и просеите весь файл через парсер, сохраняя / манипулируя (например, отправляя в БД или отображение в HTML) только необходимой вам информации.

Хотя это, как правило, не является хорошей практикой, вы можете отключить буферизацию вывода перед входом в длинный цикл синтаксического анализа XML, выводящий HTML, как только он у вас есть, и запустим () время от времени. Это приведет к передаче HTML-файла на HTTP-сервер, за счет меньшего объема памяти в процессе PHP, за счет слегка уступающего сжатия (если вы выведете фрагменты HTML более чем на 40K, разница будет незначительной) и пропорционально лучше реагировать ( пользователь «видит» что-то происходит быстрее, даже если полное завершение операции занимает немного больше времени. Опыт заключается в более быстрой нагрузке).

Полный ссылочный код для мыла Response XML-файл здесь. Как разобрать, мы увидим ниже примерный код

 <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <soap:Body> <xyzResponse xmlns="http://tempuri.org/"> <xyzResult> <xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true"> <xs:complexType> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="Table"> <xs:complexType> <xs:sequence> <xs:element name="myCityID" type="xs:int" minOccurs="0" /> <xs:element name="myCityName" type="xs:string" minOccurs="0" /> <xs:element name="myLat" type="xs:double" minOccurs="0" /> <xs:element name="myLon" type="xs:double" minOccurs="0" /> </xs:sequence> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> </xs:element> </xs:schema> <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1"> <NewDataSet xmlns=""> <Table diffgr:id="Table1" msdata:rowOrder="0"> <CityID>1</CityID> <CityName>Ahmedabad</CityName> <Lat>23.045839</Lat> <Lon>72.550578</Lon> </Table> <Table diffgr:id="Table2" msdata:rowOrder="1"> <CityID>21</CityID> <CityName>Amritsar</CityName> <Lat>31.705603</Lat> <Lon>74.807337</Lon> </Table> </NewDataSet> </diffgr:diffgram> </xyzResult> </xyzResponse> </soap:Body> </soap:Envelope> 

используя этот код, вы можете легко получить все данные Таблиц в переменной $ title и использовать это, вы можете легко легко получить любое конкретное значение …

  <?php ini_set('soap.wsdl_cache_enabled', 0); ini_set('soap.wsdl_cache_ttl', 900); ini_set('default_socket_timeout', 15); $apiauth =array('UserName'=>'USENAME','Password'=>'PASSWORD','UserCode'=>'1991'); $wsdl = 'http://SITENAME.com/service.asmx?WSDL'; try { $soap = new SoapClient($wsdl); $header = new SoapHeader('http://tempuri.org/', 'AuthHeader', $apiauth); $soap->__setSoapHeaders($header); $data = $soap->methodname($header); } catch(Exception $e) { die($e->getMessage()); } // echo "<pre>"; // print_r($data->xyzResult->any); $response = $data->xyzResult->any; $sxe = new SimpleXMLElement($response); $sxe->registerXPathNamespace('d', 'urn:schemas-microsoft-com:xml-diffgram-v1'); $result = $sxe->xpath("//NewDataSet"); echo "<pre>"; foreach ($result[0] as $title) { print_r($title); } die; ?>