2012-07-03 19 views
5

Llamar a un servicio web desde mi controlador:de análisis de respuesta SOAP

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

me sale esto:

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

¿Cómo puedo analizar estos datos y usarlo?

+0

¿Cómo es esto diferente de usted antes [pregunta] (http://stackoverflow.com/questions/11310476/soapclient-parse-result)? – bluevector

Respuesta

10

No dejas muy claro qué es el "uso", pero evidentemente necesitas algún tipo de análisis/búsqueda de XML.

Por ejemplo, intente xml-loading esa cadena y var_dump el resultado. Simplemente enumerar las diversas propiedades debería mostrarle las oportunidades.

Más adelante, puede probar XPath search y más "trucos" avanzados para acelerar el trabajo.

// 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"; 
    } 

Hay varios analizadores que puede utilizar, este es uno rápido y sucio.

Ver más here.

grandes conjuntos de datos

Nota: para grandes conjuntos de datos XML, I've found out that foreach is best.

Y para grandes conjuntos de datos en la que sólo necesita un par de información, y todo el archivo podría no caben en la memoria disponible, es probable que desee utilizar XMLParser o XMLReader y tamizar todo el archivo a través del analizador mientras mantener/manipular (por ejemplo, enviar un DB, o mostrar a HTML) solo la información que necesita.

Si bien esto no es una buena práctica general, puede desactivar el almacenamiento en búfer de salida antes de ingresar un bucle largo de análisis XML, generando HTML tan pronto como lo tenga y descarga() de vez en cuando. Esto externalizará el código HTML al servidor HTTP, ocupando menos memoria en el proceso de PHP, a expensas de una compresión ligeramente inferior (si emite trozos de HTML de más de 40K, la diferencia es insignificante) y proporcionalmente una mejor capacidad de respuesta (el el usuario "ve" que algo sucede más rápido, incluso si la finalización total de la operación lleva un poco más de tiempo. La experiencia es la de una carga más rápida).

+1

Solo iba a sugerir simpleXML. +1 –

+0

Gracias por la solución. Eliminar el espacio de nombres es la solución perfecta. –

1

completo Código de Referencia Para Jabón Respuesta de archivo XML Aquí cómo analizar veremos en más adelante ejemplo de código

<?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> 

utilizando este código se puede conseguir con facilidad todos los datos de las Tablas en la variable $ título y el uso que se puede obtener fácilmente cualquier valor específico fácilmente ...

<?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; 
    ?> 
+0

La línea $ response = $ data-> xyzResult-> any estaba dando como resultado un error debido al formato XML dentro de SimpleXMLElement. En cambio, activé el rastreo en el constructor de SoapClient y usé $ soap -> __ getLastResponse() y funcionó. Muchas gracias, ¡salvaste mi día! –

Cuestiones relacionadas