• Publicidad

Convertir Mensaje SOAP....

¿Ya sabes lo que es una referencia? Has progresado, el nível básico es cosa del pasado y ahora estás listo para el siguiente nivel.

Convertir Mensaje SOAP....

Notapor caribesoft » 2006-07-11 10:08 @464

Hola Perlianos:

Tengo un script que envía un mensaje SOAP a un servidor y recibo respuesta a través del Web Service; mi pregunta es:

¿Cómo puedo convertir "La Respuesta", que viene en XML a una estructura de datos en Perl? Este es mi script:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use LWP::UserAgent;
  4. use HTTP::Request::Common;
  5. print "Content-Type: text/xml; charset=utf-8";
  6.  
  7. my $barco   = 'ARGOSY';
  8. my $manif   = '465';
  9. my $usuario = 'API940504EPA';
  10. my $message = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
  11.       <soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
  12.          xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"
  13.          xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">
  14.          <soap:Header>
  15.            <EncabezadoSOAP xmlns=\"http://Recintos/ServiciosWebXml/\">
  16.                <idUsuario>$usuario</idUsuario>
  17.                <firma>1239</firma>
  18.                <ipCliente></ipCliente>
  19.            </EncabezadoSOAP>
  20.          </soap:Header>
  21.       <soap:Body>
  22.            <consultaUnManifiesto xmlns=\"http://Recintos/ServiciosWebXml/\">
  23.               <manifiesto>$manif</manifiesto>
  24.               <buque>$barco</buque>
  25.           </consultaUnManifiesto>
  26.      </soap:Body>
  27.    </soap:Envelope>";
  28.  
  29. my $userAgent = LWP::UserAgent->new();
  30. my $request = HTTP::Request->new(POST => 'http://192.168.240.148/wsrefis/RecintosFis.asmx?WSDL');
  31. $request->header(SOAPAction => '"http://Recintos/ServiciosWebXml/consultaUnManifiesto"');
  32. $request->content($message);
  33. $request->content_type("text/xml; charset=utf-8");
  34. my $response = $userAgent->request($request);
  35.  
  36. if($response->code == 200) {
  37.         print $response->as_string;
  38. }
  39. else {
  40.         print $response->error_as_HTML;
  41. }
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


Lo que deseo hacer es capturar y luego desplegar la información de la consulta, para posteriormente pasarla a una tabla MySQL, ¿¿¿se puede hacer esto???

De antemano, muchas gracias por sus tips,

Caribesoft...
caribesoft
Perlero nuevo
Perlero nuevo
 
Mensajes: 73
Registrado: 2006-05-09 22:01 @959
Ubicación: Cancun

Publicidad

Re: Convertir Mensaje SOAP....

Notapor explorer » 2006-07-11 12:14 @551

Depende del aspecto del xml que te devuelva...

Si es un xml simple, entonces XML::Simple te da una solución muy rápida (de hecho, es el único que he tenido que utilizar siempre):
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl -l
  2. use XML::Simple;
  3. use Data::Dumper;     # Para el volcado de la estructura
  4.  
  5. my $xml_crudo = <<XML;
  6. <?xml version="1.0" encoding="UTF-8"?>
  7. <respuesta>
  8.         <item numero="1">
  9.                 <cliente>
  10.                         <nombre>Joaquin Ferrero</nombre>
  11.                         <domicilio>Angustias, 13</domicilio>
  12.                         <postal>47001</postal>
  13.                 </cliente>
  14.                 <cliente>
  15.                         <nombre>Adosio Perez</nombre>
  16.                         <domicilio>Angustias, 15</domicilio>
  17.                         <postal>47001</postal>
  18.                 </cliente>
  19.         </item>
  20.         <item numero="3">
  21.                 <cliente>
  22.                         <nombre>Andrea Siguenza</nombre>
  23.                         <domicilio>Corral, 123</domicilio>
  24.                         <postal>47021</postal>
  25.                         </cliente>
  26.         </item>
  27. </respuesta>
  28. XML
  29.  
  30. my $xml = XMLin( $xml_crudo, ForceArray => [qw(item cliente)] );
  31.  
  32. print Dumper $xml;  # Saca la estructura Perl leída
  33.  
  34. print $xml->{item}[1]{cliente}[0]{nombre};
  35.  
  36. __OUTPUT__
  37. $VAR1 = {
  38.           'item' => [
  39.                     {
  40.                       'numero' => '1',
  41.                       'cliente' => [
  42.                                    {
  43.                                      'domicilio' => 'Angustias, 13',
  44.                                      'postal' => '47001',
  45.                                      'nombre' => 'Joaquin Ferrero'
  46.                                    },
  47.                                    {
  48.                                      'domicilio' => 'Angustias, 15',
  49.                                      'postal' => '47001',
  50.                                      'nombre' => 'Adosio Perez'
  51.                                    }
  52.                                  ]
  53.                     },
  54.                     {
  55.                       'numero' => '3',
  56.                       'cliente' => [
  57.                                    {
  58.                                      'domicilio' => 'Corral, 123',
  59.                                      'postal' => '47021',
  60.                                      'nombre' => 'Andrea Siguenza'
  61.                                    }
  62.                                  ]
  63.                     }
  64.                   ]
  65.         };
  66.  
  67. Andrea Siguenza
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


La única pega es que a veces te tienes que pegar durante horas con las opciones que tienes que pasar a XMLin() para tener la estructura de datos que quieres. Pero ya digo, si el xml es simple, la solución es muy rápida. Otra opción es usar XML::Dumper, pero yo no lo he probado. Quizás hasta sea mejor...

Si necesitas algo más 'inteligente', hay otros módulos XML que son muy interesantes, como el XML::Smart o el más famoso, XML::Twig. En CPAN hay algunos más...

Y luego pasar la consulta a una base de datos, quizás XML::RDB o DBIx::DBStag te ayude, además de la solución obvia de hacer un INSERT con los datos obtenidos del xml...
Última edición por explorer el 2006-07-12 05:11 @258, editado 2 veces en total
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor explorer » 2006-07-11 12:22 @557

Humm... si estamos hablando de SOAP... mejor mira antes aquí...
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Esto es lo que recibo

Notapor caribesoft » 2006-07-13 03:40 @194

Muchas gracias Explorer por el tip, ya estuve leyendo la documentación pero sigo con dudas. Mira, ésta es la respuesta al mensaje enviado que recibo. ¿ Qué me recomiendas ?

Sintáxis: [ Descargar ] [ Ocultar ]
Using xml Syntax Highlighting
<?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>
    <consultaUnManifiestoResponse xmlns="http://Recintos/ServiciosWebXml/">
      <consultaUnManifiestoResult>
        <error>0</error>
        <descripError/>
        <registros>1</registros>
        <man>
          <nTrans>465</nTrans>
          <cTransp>HYBU</cTransp>
          <idTransp>7116834     </idTransp>
          <nomBuque>ARGOSY</nomBuque>
          <numViaje>416 SB MEX</numViaje>
          <fecEstimada>15/12/2004 12:00:00 AM</fecEstimada>
          <tipoOper>1</tipoOper>
          <lineaNaviera>NAVIERA VICANE</lineaNaviera>
          <fecRecibe>14/12/2004 4:09:46 PM</fecRecibe>
          <cuAduana>53</cuAduana>
          <cuPais>ATG</cuPais>
          <cuPuerto>PMS</cuPuerto>
          <cuEntidadMan>1158</cuEntidadMan>
          <casos/>
        </man>
        <manifiestos>
          <anyType xsi:type="ObjManifiesto">
            <nTrans>465</nTrans>
            <cTransp>HYBU</cTransp>
            <idTransp>7116834     </idTransp>
            <nomBuque>ARGOSY</nomBuque>
            <numViaje>416 SB MEX</numViaje>
            <fecEstimada>15/12/2004 12:00:00 AM</fecEstimada>
            <tipoOper>1</tipoOper>
            <lineaNaviera>NAVIERA VICANE</lineaNaviera>
            <fecRecibe>14/12/2004 4:09:46 PM</fecRecibe>
            <cuAduana>53</cuAduana>
            <cuPais>ATG</cuPais>
            <cuPuerto>PMS</cuPuerto>
            <cuEntidadMan>1158</cuEntidadMan>
            <casos/>
          </anyType>
        </manifiestos>
      </consultaUnManifiestoResult>
    </consultaUnManifiestoResponse>
  </soap:Body>
</soap:Envelope>
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
caribesoft
Perlero nuevo
Perlero nuevo
 
Mensajes: 73
Registrado: 2006-05-09 22:01 @959
Ubicación: Cancun

Notapor explorer » 2006-07-13 05:28 @269

Nada, nada... SOAP::Lite
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use SOAP::Lite;
  3.  
  4. my $d = SOAP::Custom::XML::Deserializer
  5.   -> deserialize(join '', <DATA>)
  6.   -> valueof('/Envelope/Body');
  7.  
  8. # Volcado de toda la estructura para ver su aspecto
  9. #use Data::Dumper;
  10. #print Dumper $d;
  11.  
  12. # Acceso por programa a algunos datos
  13. my $man = $d->consultaUnManifiestoResponse->consultaUnManifiestoResult->man;
  14. my @campos = qw(
  15.     nTrans          cTransp         idTransp        nomBuque
  16.     numViaje        fecEstimada     tipoOper        lineaNaviera
  17.     fecRecibe       cuAduana        cuPais          cuPuerto
  18.     cuEntidadMan    casos
  19.  );
  20.  
  21. foreach my $campo ( @campos ) {
  22.     print "$campo: ", $man->$campo,"\n";
  23. }
  24.  
  25. # Acceso directo a un elemento concreto
  26. print "manifiestos/cTransp: ",
  27.     $d  ->consultaUnManifiestoResponse
  28.             ->consultaUnManifiestoResult
  29.                 ->manifiestos
  30.                     ->anyType
  31.                         ->cTransp,
  32.    "\n";
  33.  
  34. __DATA__
  35. <?xml version="1.0" encoding="utf-8"?>
  36. <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">
  37.     <soap:Body>
  38.         <consultaUnManifiestoResponse xmlns="http://Recintos/ServiciosWebXml/">
  39.             <consultaUnManifiestoResult>
  40.                 <error>0</error>
  41.                 <descripError />
  42.                 <registros>1</registros>
  43.                 <man>
  44.                     <nTrans>465</nTrans>
  45.                     <cTransp>HYBU</cTransp>
  46.                     <idTransp>7116834     </idTransp>
  47.                     <nomBuque>ARGOSY</nomBuque>
  48.                     <numViaje>416 SB MEX</numViaje>
  49.                     <fecEstimada>15/12/2004 12:00:00 AM</fecEstimada>
  50.                     <tipoOper>1</tipoOper>
  51.                     <lineaNaviera>NAVIERA VICANE</lineaNaviera>
  52.                     <fecRecibe>14/12/2004 4:09:46 PM</fecRecibe>
  53.                     <cuAduana>53</cuAduana>
  54.                     <cuPais>ATG</cuPais>
  55.                     <cuPuerto>PMS</cuPuerto>
  56.                     <cuEntidadMan>1158</cuEntidadMan>
  57.                     <casos />
  58.                 </man>
  59.                 <manifiestos>
  60.                     <anyType xsi:type="ObjManifiesto">
  61.                         <nTrans>465</nTrans>
  62.                         <cTransp>HYBU</cTransp>
  63.                         <idTransp>7116834     </idTransp>
  64.                         <nomBuque>ARGOSY</nomBuque>
  65.                         <numViaje>416 SB MEX</numViaje>
  66.                         <fecEstimada>15/12/2004 12:00:00 AM</fecEstimada>
  67.                         <tipoOper>1</tipoOper>
  68.                         <lineaNaviera>NAVIERA VICANE</lineaNaviera>
  69.                         <fecRecibe>14/12/2004 4:09:46 PM</fecRecibe>
  70.                         <cuAduana>53</cuAduana>
  71.                         <cuPais>ATG</cuPais><cuPuerto>PMS</cuPuerto>
  72.                         <cuEntidadMan>1158</cuEntidadMan>
  73.                         <casos />
  74.                     </anyType>
  75.                 </manifiestos>
  76.             </consultaUnManifiestoResult>
  77.         </consultaUnManifiestoResponse>
  78.     </soap:Body>
  79. </soap:Envelope>
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

Salida:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
nTrans: 465
cTransp: HYBU
idTransp: 7116834
nomBuque: ARGOSY
numViaje: 416 SB MEX
fecEstimada: 15/12/2004 12:00:00 AM
tipoOper: 1
lineaNaviera: NAVIERA VICANE
fecRecibe: 14/12/2004 4:09:46 PM
cuAduana: 53
cuPais: ATG
cuPuerto: PMS
cuEntidadMan: 1158
casos:
manifiestos/cTransp: HYBU
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

Y esto dándole a SOAP::Lite el xml de forma directa, pero si ves la carpeta de ejemplos verás que puedes hacer todo el diálogo con el servidor sin ver ni una línea de xml.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Otra preguntica

Notapor caribesoft » 2006-07-13 15:18 @679

Explorer :

Ya probé tu ejemplo y funciona de maravilla, gracias, y perdón por mi ignorancia, soy nuevo en esto del SOAP, y tengo otra preguntita :

¿Cómo le hago para que la respuesta del mensaje SOAP recibido quede dentro de _DATA_ ?

Es decir: my $response ????

Gracias de antemano por tu ayuda, he buscado en toda la Web ¡¡¡ y me has dado el mejor ejemplo !!!

Caribesoft,
caribesoft
Perlero nuevo
Perlero nuevo
 
Mensajes: 73
Registrado: 2006-05-09 22:01 @959
Ubicación: Cancun

Notapor explorer » 2006-07-13 16:29 @728

El ejemplo lo he sacado de la carpeta de ejemplos de SOAP::Lite, como te dije... revísalo por favor, porque es posible que esté lo que necesites.

Vamos a ver... antes hay que aclarar cómo vas a trabajar...

El SOAP es un protocolo para intercambiar información. O, mejor dicho, para ejecutar procedimientos en servicios HTTP remotos como si estuvieran en nuestro propio programa o equipo. Y utiliza el XML como base para intercambiar esa información... pero eso no quiere decir que tengamos que 'ver' el XML. Fíjate que en mi ejemplo, el xml se 've' porque está en la sección DATA, pero si fuera una petición SOAP normal, ni lo vería (porque no haría falta).

Entonces...
* ¿No puedes/quieres hablar con el servidor de forma directa?
* ¿O estás obligado a trabajar con el XML?

Entra en SOAP::Lite y mira los ejemplos que hay en la SYNOPSIS, para que veas que dialogar con el servidor no implica tener que ver el XML para nada...

Si, de todas formas, estás obligado a trabajar con el XML, lo puedes grabar a un fichero y leerlo luego como lo he leído la sección DATA. O si el resultado de la petición ya la tienes en una variable escalar, no necesitas nada más que meterla en el deserialize.

La sección DATA sirve para meter datos, configuraciones, comentarios y demás que sólo le interesan a ese programa. No se puede meter nada en él (bueno... yo creo que sí :-) , pero no lo recomiendo... )

¿No puedes darnos más pistas de cómo realizas toda la transacción?
Última edición por explorer el 2006-07-14 06:05 @295, editado 1 vez en total
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Es cierto, te explico desde el principio

Notapor caribesoft » 2006-07-13 21:14 @926

Nuevamente gracias por tu atención y apoyo, pero tienes razón te voy a explicar qué es lo que necesito realmente:

1. Desarrollé un sistema para el control del manejo de mercancía de importación y exportación de un muelle o almacén fiscal. (En Perl y MySql).

2. El "Documento Fuente" que es la base de la información del sistema, se llama "Manifiesto", el cual tiene a detalle la información de la mercancía que llega como importación al puerto.

3. Actualmente este documento es recibido dos días antes de la llegada del barco y es manipulada sólo en papel, posteriormente se "captura" en el sistema para mejorar el control.

4. Los encargados de generar esta información de los "Manifiestos", acaban de liberar un sistema, por medio del cual se puede consultar dicha información por internet, a través de Web Services.

5. La primera parte que deseo hacer es la consulta de los "Manifiestos" y esta se debe hacerse por medio de un mensaje SOAP para consultar los datos generales, es el script que te muestro arriba.

6. La segunda parte que necesito hacer, es transferir la información de los manifiestos, vía web services, a las bases de datos (MySql) de mi sistema, para evitar la captura manual de dicha información.

En general eso es lo que quiero hacer.

Hace un rato, por fin puede ver la respuesta a mi mensaje como un documento XML, y allí es donde a mi me gustaría poder manipularlo para generar una pantalla de consulta en mi sistema.

Bueno, espero que me haya podido dar a entender y nuevamente mil gracias por adelantado..

saludos,
Caribesoft
caribesoft
Perlero nuevo
Perlero nuevo
 
Mensajes: 73
Registrado: 2006-05-09 22:01 @959
Ubicación: Cancun

Notapor explorer » 2006-07-14 07:07 @338

Yo estoy convencido de que si dispones del documento WSDL que define la petición, tu script de más arriba se puede reducir a unas 5 líneas, cuya respuesta quedaría en una variable como la $d en mi script, a partir de la cual puedes acceder a su contenido y luego meterla en la base de datos.

Vamos, es lo que yo haría... Otra forma sería meter tu $response->as_astring dentro del deserialize para acceder a los datos, como está indicado en mi script... y de allí a la base de datos...

Yo creo que todo el programa no debe ocupar más de 50 líneas (comentarios incluidos). Lo malo es que aquí no dispongo de un servidor SOAP con el que hacer pruebas... podría montar uno con el mismo módulo SOAP::Lite, pero ahora mismo no tengo tiempo...
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Tienes razon

Notapor caribesoft » 2006-07-14 12:26 @560

Tienes razon, y gracias a tu ayuda ya entendi un poco mas como funciona el SOAP::Lite, voy hacer algunas pruebas y luego te comento los resultados, nuevamente muchas gracias ...
caribesoft
Perlero nuevo
Perlero nuevo
 
Mensajes: 73
Registrado: 2006-05-09 22:01 @959
Ubicación: Cancun

Siguiente

Volver a Intermedio

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 3 invitados

cron