Página 1 de 1

Acceder a un string XML de Web service

NotaPublicado: 2014-07-25 12:20 @555
por piero66
Hola, buenos días.

Sucede que consumo un Web Service que me regresa un string de tipo XML, pero no sé cómo acceder a los datos.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $serviceWsdl = "http://192.1.1.1:8080/services/Ws?wsdl";
  2. my $soap = SOAP::Lite->service($serviceWsdl);
  3. mu $param = "valores";
  4. $result =  $soap->servicio($param);
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Al parecer $result debe contener algo como esto:
Sintáxis: [ Descargar ] [ Ocultar ]
Using xml Syntax Highlighting
  1. <S>
  2.         <SEC>
  3.                 <NONCE></NONCE>
  4.         </SEC>
  5.         <RES>
  6.                 <EXITO></EXITO>
  7.                 <CODIGO></CODIGO>              
  8.         </RES>
  9.         <PAR>
  10.                 <SOLICITUD>
  11.                         <EJE_SOL></EJE_SOL>
  12.                         <NUM_SOL></NUM_SOL>
  13.                         <FECHA_SOL></FECHA_SOL>                
  14.                         <TITULAR>
  15.                                         <TIPODOCUMENTO></TIPODOCUMENTO>
  16.                                         <DOCUMENTO></DOCUMENTO>
  17.                                         <NOM_TIT></NOM_TIT>                                    
  18.                         </TITULAR>
  19.                         <REPRESENTANTE>
  20.                                         <DOCUMENTO></DOCUMENTO>
  21.                                         <NOM_REP></NOM_REP>                                    
  22.                         </REPRESENTANTE>
  23.                         <NUM_REG></NUM_REG>                                            
  24.                         <L_VARIABLES>
  25.                                 <VARIABLE>
  26.                                         <CODIGO></CODIGO>
  27.                                         <ETIQUETA></ETIQUETA>                                  
  28.                                 </VARIABLE>
  29.                         </L_VARIABLES>
  30.                         <L_DOC>
  31.                                 <DOC>
  32.                                         <DAT></DAT>
  33.                                         <NOM></NOM>
  34.                                         <EXT></EXT>                                    
  35.                                 </DOC>
  36.                         </L_DOC>
  37.                 </SOLICITUD>
  38.         </PAR>
  39. </S>
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

No sé cómo acceder a cada uno de los tags.

¿Me podrían apoyar?
¡ Gracias anticipadas !

Re: Acceder a un string XML de Web service

NotaPublicado: 2014-07-25 13:36 @608
por explorer
Sí que se podría usar XML::Simple.

Antes, mira estos otros hilos, para ver otras opciones:
Hay otros hilos parecidos. Usa el sistema de búsqueda. Si no te valen esos métodos, tendrás que usar XML::Simple, del que también hemos hablado mucho y hay muchos ejemplos. Usa el sistema de búsqueda.

Si no lo ves claro, vuelve a preguntar aquí.

Re: Acceder a un string XML de Web service

NotaPublicado: 2014-07-25 13:52 @620
por piero66
Hola, sí que he visto los enlaces anteriormente, pero se me hacen confusos. De hecho ahí fue que vi algo como esto:

use XML::Simple; y lo he declarado en mi ejemplo, pero la verdad no sé cómo utilizarlo ya en los datos específicos (XML) que me regresa el Web service.

Re: Acceder a un string XML de Web service

NotaPublicado: 2014-07-25 17:21 @764
por explorer
A ver, ya te digo que es fácil si ves los ejemplos que ya existen en estos hilos. Busca por XML::Simple.

Verás que hay que pasar el xml a XMLin(), y luego ya podrás acceder al contenido.

Eso sí... el problema de XML::Simple es que la palabra 'Simple' engaña... No quiere decir que el acceso al xml sea sencillo, sino que lo que es sencillo es el propio módulo... con lo que a veces va a hacer cosas que no queremos o comprendemos.

Re: Acceder a un string XML de Web service

NotaPublicado: 2014-07-25 17:46 @782
por piero66
Sí, de hecho ya lo modifiqué y puedo obtener todos los datos:

my $result = $xml->XMLin($soap->servicio($datos), forcearray => 1);

imprime_elemento("Datos",$result,"");

sub imprime_elemento {
my $nombre = shift;
my $elemento = shift;
my $indentacion = shift;
print $indentacion . "" . $nombre . "<br>";
$indentacion .= " ";
foreach my $clave (keys %$elemento) {
if (ref $elemento->{$clave} eq "ARRAY") {
foreach my $subelemento (@{$elemento->{$clave}}) {
if (ref $subelemento eq "HASH") {
imprime_elemento($clave, $subelemento,$indentacion);
} else {
print $indentacion . "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ELEMENTO: " . $clave . ", Valor: " . $subelemento . "<br";
}
}
} else {
print $indentacion . "Atributo: " . $clave . ". Valor: " . $elemento->{$clave} . "<br>";
}
}
}

pero, francamente, no sé cómo acceder, por ejemplo a esta marca: <NUM_SOL> que ya está guardado dentro de la cadena $result.

<S>

<PAR>
<SOLICITUD>
<NUM_SOL></NUM_SOL>
</SOLICITUD>
</PAR>
</S>

No sé si me expliqué, explorer, perdón, ¡¡ me hice muchas bolas !!

Re: Acceder a un string XML de Web service

NotaPublicado: 2014-07-25 20:30 @895
por explorer
Has leído poco...

Cuando no sabemos qué aspecto tiene algo, podemos hacer un volcado para verlo.

Ejemplo. Con el siguiente programa vemos el contenido del xml interpretado por XML::Simple:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use v5.14;
  3. use File::Slurp;
  4. use XML::Simple;
  5.  
  6. my $xmlfile = read_file('code_37483_1.xml');
  7.  
  8. my $xs = XML::Simple->new();
  9.  
  10. my $xml = $xs->XMLin( $xmlfile, forcearray => 1 );
  11.  
  12. use Data::Dumper;
  13. say Dumper $xml;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Esta es la salida:
Sintáxis: [ Descargar ] [ Ocultar ]
Using xml Syntax Highlighting
  1. $VAR1 = {
  2.           'SEC' => [
  3.                    {
  4.                      'NONCE' => [
  5.                                 {}
  6.                               ]
  7.                    }
  8.                  ],
  9.           'PAR' => [
  10.                    {
  11.                      'SOLICITUD' => [
  12.                                     {
  13.                                       'REPRESENTANTE' => [
  14.                                                          {
  15.                                                            'DOCUMENTO' => [
  16.                                                                           {}
  17.                                                                         ],
  18.                                                            'NOM_REP' => [
  19.                                                                         {}
  20.                                                                       ]
  21.                                                          }
  22.                                                        ],
  23.                                       'L_VARIABLES' => [
  24.                                                        {
  25.                                                          'VARIABLE' => [
  26.                                                                        {
  27.                                                                          'CODIGO' => [
  28.                                                                                      {}
  29.                                                                                    ],
  30.                                                                          'ETIQUETA' => [
  31.                                                                                        {}
  32.                                                                                      ]
  33.                                                                        }
  34.                                                                      ]
  35.                                                        }
  36.                                                      ],
  37.                                       'NUM_SOL' => [
  38.                                                    'X'
  39.                                                  ],
  40.                                       'NUM_REG' => [
  41.                                                    {}
  42.                                                  ],
  43.                                       'FECHA_SOL' => [
  44.                                                      {}
  45.                                                    ],
  46.                                       'L_DOC' => [
  47.                                                  {
  48.                                                    'DOC' => [
  49.                                                             {
  50.                                                               'EXT' => [
  51.                                                                        {}
  52.                                                                      ],
  53.                                                               'NOM' => [
  54.                                                                        {}
  55.                                                                      ],
  56.                                                               'DAT' => [
  57.                                                                        {}
  58.                                                                      ]
  59.                                                             }
  60.                                                           ]
  61.                                                  }
  62.                                                ],
  63.                                       'TITULAR' => [
  64.                                                    {
  65.                                                      'DOCUMENTO' => [
  66.                                                                     {}
  67.                                                                   ],
  68.                                                      'NOM_TIT' => [
  69.                                                                   {}
  70.                                                                 ],
  71.                                                      'TIPODOCUMENTO' => [
  72.                                                                         {}
  73.                                                                       ]
  74.                                                    }
  75.                                                  ],
  76.                                       'EJE_SOL' => [
  77.                                                    {}
  78.                                                  ]
  79.                                     }
  80.                                   ]
  81.                    }
  82.                  ],
  83.           'RES' => [
  84.                    {
  85.                      'CODIGO' => [
  86.                                  {}
  87.                                ],
  88.                      'EXITO' => [
  89.                                 {}
  90.                               ]
  91.                    }
  92.                  ]
  93.         };
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

Vemos que XML::Simple ha generado un array por cada marca. Eso es debido a la presencia de la opción ForceArray => 1.

Entonces para acceder a 'NUM_SOL' usaremos algo como esto:

$xml->{PAR}->[0]->{SOLICITUD}->[0]->{NUM_SOL}->[0];

Si lo ponemos a 0, sale algo completamente distinto:
Sintáxis: [ Descargar ] [ Ocultar ]
Using xml Syntax Highlighting
  1. $VAR1 = {
  2.           'SEC' => {
  3.                    'NONCE' => {}
  4.                  },
  5.           'PAR' => {
  6.                    'SOLICITUD' => {
  7.                                   'REPRESENTANTE' => {
  8.                                                      'DOCUMENTO' => {},
  9.                                                      'NOM_REP' => {}
  10.                                                    },
  11.                                   'L_VARIABLES' => {
  12.                                                    'VARIABLE' => {
  13.                                                                  'CODIGO' => {},
  14.                                                                  'ETIQUETA' => {}
  15.                                                                }
  16.                                                  },
  17.                                   'NUM_SOL' => 'X',
  18.                                   'NUM_REG' => {},
  19.                                   'FECHA_SOL' => {},
  20.                                   'L_DOC' => {
  21.                                              'DOC' => {
  22.                                                       'EXT' => {},
  23.                                                       'NOM' => {},
  24.                                                       'DAT' => {}
  25.                                                     }
  26.                                            },
  27.                                   'TITULAR' => {
  28.                                                'DOCUMENTO' => {},
  29.                                                'NOM_TIT' => {},
  30.                                                'TIPODOCUMENTO' => {}
  31.                                              },
  32.                                   'EJE_SOL' => {}
  33.                                 }
  34.                  },
  35.           'RES' => {
  36.                    'CODIGO' => {},
  37.                    'EXITO' => {}
  38.                  }
  39.         };
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
con lo que para acceder a 'NUM_SOL' sería

$xml->{PAR}->{SOLICITUD}->{NUM_SOL};

lo cual es más sencillo, claro.

Otra cosa... es muy posible que no necesites hacer la traducción a cadena de lo que te devuelve SOAP, y que la respuesta ya sea una estructura jerárquica, con lo que no necesitas XML::Simple, sino acceder a los contenidos de forma directa. Esto es lo que se comenta en el hilo Cómo leer un SOAP enlazado antes.

Es más... no necesitas nada de esto...

Según la documentación de SOAP::Lite, la respuesta de la ejecución de un método es de tipo SOAP::SOM. Entonces, tu programa podría quedar reducido a algo como esto (no probado):
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $serviceWsdl = "http://192.1.1.1:8080/services/Ws?wsdl";
  2. my $soap = SOAP::Lite->service($serviceWsdl);
  3. my $param = "valores";
  4. my $result =  $soap->servicio($param);
  5. my $res = $result->valueof('//PAR/SOLICITUD/NUM_SOL');
  6. print "$res\n";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Re: Acceder a un string XML de Web service

NotaPublicado: 2014-07-28 10:58 @499
por piero66
Muchas gracias, explorer. Me ha funcionado perfecto. Tienes razón, a veces trato de irme a los ejemplos y olvido leer la documentación.

Con estas instrucciones me ha funcionado lo que busco.

my $xs = XML::Simple->new();
$xml = $xs->XMLin( $soap->servicio($datos), forcearray => 1 );
print $xml->{PAR}->[0]->{SOLICITUD}->[0]->{NUM_SOL}->[0];

Re: Acceder a un string XML de Web service

NotaPublicado: 2014-07-28 11:32 @522
por explorer
¿No te ha funcionado lo del valueof()?

Re: Acceder a un string XML de Web service

NotaPublicado: 2014-07-28 17:58 @790
por piero66
Traté de ejecutar los dos. El primero me corre bien, el segundo me manda un error en esa parte.

Can't call method "valueof" without a package or object reference at consumeExp.cgi line 23.

Traté de instalar SOAP::SOM con cpan, pero no me dejó.

Como ya me había funcionado el primero sobre esa línea, me fui :oops:

Re: Acceder a un string XML de Web service

NotaPublicado: 2014-07-28 18:49 @826
por explorer
No tienes que instalar SOAP::SOM. Ya viene incluido con la distribución de SOAP::Lite.