Perl en Español

  1. Home
  2. Tutoriales
  3. Foro
  4. Artículos
  5. Donativos
  6. Publicidad
 

Consulta sobre XML
Ir a página 1, 2, 3, 4  Siguiente
 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Intermedio
Mensaje Mie Jun 04, 2008 1:18 pm
situ
Perlero Frecuente
Perlero Frecuente
Registrado: 09 Abr 2007
Mensajes: 143
Consulta sobre XML Responder citando

Tengo el siguiente XML, el cual me gustaria parsear con perl y que me de los resultados en pantalla.
Estoy tratando de usar XML::Simple pero la verdad que no obtengo un resultado Confused

XML:
<?xml version="1.0"?>
<owner>
<technology name="test">
<owner>
<pc>
<name>marcos</name>
<url>https://10.1.1.1</url>
<ip>10.1.1.1</ip>
<user name="admin"><password>123</password><date>20080101</date></user>
<user name="root"><password>123</password><date>20080101</date></user>
<notes>test</notes>
</pc>
<pc>
<name>marcos2</name>
<url>https://10.2.2.2</url>
<ip>10.2.2.2</ip>
<user name="root"><password>asd</password><date>20080102</date></user>
<notes>testno/notes>
</pc>
</technology>
</owner>


Gracias
Mensaje Mie Jun 04, 2008 2:26 pm
situ
Perlero Frecuente
Perlero Frecuente
Registrado: 09 Abr 2007
Mensajes: 143
Responder citando

Tengo este script pero no me entrega información :S

Perl:
#!/usr/bin/perl
use XML::Simple;
my $info = XMLin("/home/situ/test.xml");
for( @{$info->{host}} ) {
    print "$_->{name} => $_->{url} ($_->{ip})\n";
}
Mensaje Mie Jun 04, 2008 3:29 pm
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4104
Ubicación: Valladolid, España
Responder citando

* Dentro de <technology> hay un <owner> que no está cerrado
* El segundo <notes> no está bien cerrado

El correcto, creo que es este:
XML:
<?xml version="1.0"?>
<owner>
        <technology name="test">
                <pc>
                        <name>marcos</name>
                        <url>https://10.1.1.1</url>
                        <ip>10.1.1.1</ip>
                        <user name="admin"><password>123</password><date>20080101</date></user>
                        <user name="root"><password>123</password><date>20080101</date></user>
                        <notes>test</notes>
                </pc>
                <pc>
                        <name>marcos2</name>
                        <url>https://10.2.2.2</url>
                        <ip>10.2.2.2</ip>
                        <user name="root"><password>asd</password><date>20080102</date></user>
                        <notes>testno</notes>
                </pc>
        </technology>
</owner>
Mensaje Mie Jun 04, 2008 3:57 pm
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4104
Ubicación: Valladolid, España
Responder citando

Recuerda: La palabra Simple de XML::Simple se refiere a que es simple de uso no de uso simple. Humm... quiero decir que no es tan simple de usar, porque el módulo es simple... hummm... algo así.

Recuerda dos: Data::Dumper es tu amigo.

Dado el XML que te he pasado antes, con este programa:
Perl:
#!/usr/bin/perl
use strict;
use warnings;

use XML::Simple;
use Data::Dumper;

my $info = XMLin("kk.xml", KeyAttr => 1);
print Dumper($info);

for my $pc ( @{$info->{technology}{pc}} ) {
    print "$pc->{name} => $pc->{url} ($pc->{ip})\n";
}
sale
Código:
$VAR1 = {
            'technology' => {
                              'name' => 'test',
                              'pc' => [
                                        {
                                          'notes' => 'test',
                                          'ip' => '10.1.1.1',
                                          'user' => [
                                                      {
                                                        'password' => '123',
                                                        'date' => '20080101',
                                                        'name' => 'admin'
                                                      },
                                                      {
                                                        'password' => '123',
                                                        'date' => '20080101',
                                                        'name' => 'root'
                                                      }
                                                    ],
                                          'url' => 'https://10.1.1.1',
                                          'name' => 'marcos'
                                        },
                                        {
                                          'notes' => 'testno',
                                          'ip' => '10.2.2.2',
                                          'user' => {
                                                      'password' => 'asd',
                                                      'date' => '20080102',
                                                      'name' => 'root'
                                                    },
                                          'url' => 'https://10.2.2.2',
                                          'name' => 'marcos2'
                                        }
                                      ]
                            }
          };
marcos => https://10.1.1.1 (10.1.1.1)
marcos2 => https://10.2.2.2 (10.2.2.2)
Mensaje Mie Jun 04, 2008 5:14 pm
situ
Perlero Frecuente
Perlero Frecuente
Registrado: 09 Abr 2007
Mensajes: 143
Responder citando

Estoy tratando de poner más información, por ejemplo:
Perl:
#!/usr/bin/perl
use strict;
use warnings;

use XML::Simple;
use Data::Dumper;

my $info = XMLin("kk.xml", KeyAttr => 1);
##print Dumper(\$info);

for my $pc ( @{$info->{technology}{pc}} ) {
    print "$pc->{name} => $pc->{url} ($pc->{ip}) $pc->{notes} $pc->{user}->{date}\n";
    }


Obtengo "date" solamente en el segundo resultado y no en todos :S

Cita:

Pseudo-hashes are deprecated at xml.pl line 12.
Use of uninitialized value in concatenation (.) or string at xml.pl line 12.
marcos => https://10.1.1.1 (10.1.1.1) test
marcos2 => https://10.2.2.2 (10.2.2.2) testno 20080102
Mensaje Mie Jun 04, 2008 5:46 pm
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4104
Ubicación: Valladolid, España
Responder citando

Fíjate bien en el volcado (dump).

Resulta que dentro de {technology}{pc}[0]{user}, hay un array anónimo (fíjate en la presencia de unos corchetes) que contiene dos elementos, mientras que {technology}{pc}[1]{user} es un hash con los atributos de un solo usuario.

Ya hemos dicho que XML::Simple es simple de entenderas, por lo que hay que ayudarle un poco a que nos lea bien el XML.

Forzaremos a que se comporte con 'user' siempre de la misma manera. Para eso, cambiamos la línea del XMLin() a
Perl:
my $info = XMLin("kk.xml", KeyAttr => 1, ForceArray => [ 'user' ]);
Y ya tenemos
Código:
$VAR1 = {
          'technology' => {
                            'name' => 'test',
                            'pc' => [
                                      {
                                        'notes' => 'test',
                                        'ip' => '10.1.1.1',
                                        'user' => [
                                                    {
                                                      'password' => '123',
                                                      'date' => '20080101',
                                                      'name' => 'admin'
                                                    },
                                                    {
                                                      'password' => '123',
                                                      'date' => '20080101',
                                                      'name' => 'root'
                                                    }
                                                  ],
                                        'url' => 'https://10.1.1.1',
                                        'name' => 'marcos'
                                      },
                                      {
                                        'notes' => 'testno',
                                        'ip' => '10.2.2.2',
                                        'user' => [
                                                    {
                                                      'password' => 'asd',
                                                      'date' => '20080102',
                                                      'name' => 'root'
                                                    }
                                                  ],
                                        'url' => 'https://10.2.2.2',
                                        'name' => 'marcos2'
                                      }
                                    ]
                          }
        };

con lo que con el programa
Perl:
for my $pc ( @{$info->{technology}{pc}} ) {
    print "$pc->{name} => $pc->{url} ($pc->{ip})\n";
    for my $user ( @{$pc->{user}} ) {
        print "\t$user->{name} : $user->{date}\n";
    }
}
sale
Código:
marcos => https://10.1.1.1 (10.1.1.1)
        admin : 20080101
        root : 20080101
marcos2 => https://10.2.2.2 (10.2.2.2)
        root : 20080102
Mensaje Mie Jun 04, 2008 5:50 pm
situ
Perlero Frecuente
Perlero Frecuente
Registrado: 09 Abr 2007
Mensajes: 143
Responder citando

La verdad que muchas gracias, siempre me ayudas en lo que necesito.
Mensaje Jue Jun 05, 2008 7:21 pm
situ
Perlero Frecuente
Perlero Frecuente
Registrado: 09 Abr 2007
Mensajes: 143
Responder citando

Explorer,
Te hago una consulta: ¿hay forma de dividir, por ejemplo

Perl:

for my $pc ( @{$info->{technology}{pc}} ) {
    print "$pc->{name} => $pc->{url} ($pc->{ip})\n";
    for my $user ( @{$pc->{user}} ) {
        print "\t$user->{name} : $user->{date}\n";
    }
}
?

Porque me gustaría hacer en el script un tipo de buscador, donde yo, poniendo por ejemplo
bash:
perl miscript.pl -name marcos

me muestre la información de esa PC.
Mensaje Jue Jun 05, 2008 8:00 pm
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4104
Ubicación: Valladolid, España
Responder citando

Con el siguiente programa
Perl:
#!/usr/bin/perl -s
use XML::Simple;
use strict;
use warnings;

our $name;
my $info = XMLin("kk.xml", KeyAttr => 1, ForceArray => [ 'user' ]);
my $host = $name || '.+';

for my $pc ( @{$info->{technology}{pc}} ) {

    next if $pc->{name} !~ /^$host$/;

    print "$pc->{name} => $pc->{url} ($pc->{ip})\n";
    for my $user ( @{$pc->{user}} ) {
        print "\t$user->{name} : $user->{date}\n";
    }
}
invocándolo con
Código:
./kk.pl -name=marcos
sale
Código:
marcos => https://10.1.1.1 (10.1.1.1)
        admin : 20080101
        root : 20080101

Notas:
* Hemos puesto un flag '-s' al principio, para que haga el procesamiento de los argumentos. Es algo simplón, pero efectivo para cosas pequeñas
* Agregamos la línea del 'our' para indicar la presencia de una variable global (la que Perl usará para guardar el valor del parámetro pasado por el usuario)
* Creamos y definimos la variable $host, que guardará el nombre de la máquina, o (||) una expresión regular que coincidirá con cualquier nombre de máquina. Esto lo hacemos para el caso de que el usuario no ponga ningún parámetro y salgan entonces todas las máquinas
* Agregamos la línea del next, para filtrar los $pc que coinciden con nuestro nombre de $host. Observar el hecho de que, realmente, estamos admitiendo como nombre de máquina una expresión regular. Podríamos haber ejecutado el programa con ./kk.pl -name=marcos.* y saldrán todas las máquinas cuyo nombre empiece por 'marcos'.
Mensaje Vie Jun 06, 2008 8:16 am
situ
Perlero Frecuente
Perlero Frecuente
Registrado: 09 Abr 2007
Mensajes: 143
Responder citando

Muchísimas gracias, espero no tener que molestar con alguna consulta.
Mensaje Vie Jun 06, 2008 8:22 am
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4104
Ubicación: Valladolid, España
Responder citando

Las consultas nunca molestan. Siempre aprendemos todos.
Mensaje Vie Jun 06, 2008 10:30 am
situ
Perlero Frecuente
Perlero Frecuente
Registrado: 09 Abr 2007
Mensajes: 143
Responder citando

Ya voy entendiendo el script :d, pero me hago un lío con los next if, porque mi idea es buscar por todos los parámetros no solo host, sino usuario, password, date.

Me podrías dar una manito Very Happy Gracias
Mensaje Vie Jun 06, 2008 10:52 am
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4104
Ubicación: Valladolid, España
Responder citando

Bueno, yo he puesto esa solución porque solo comentaste que querías buscar la información de un ordenador.

Tendrás que modificarlo para hacer la búsqueda por otros elementos. Por ejemplo, buscar por usuario consistiría en agregar otro next dentro del bucle for interior.
Mensaje Vie Jun 06, 2008 4:26 pm
situ
Perlero Frecuente
Perlero Frecuente
Registrado: 09 Abr 2007
Mensajes: 143
Responder citando

Consulta agregar para ver las notas y no me lo toma, me entrega el resultado de todos.

Perl:

#!/usr/bin/perl -s
use XML::Simple;
use strict;
use warnings;

our $name;
my $info = XMLin("kk.xml", KeyAttr => 1, ForceArray => [ 'user' ]);
my $host = $name || '.+';
my $notes = $name || '.+';

for my $pc ( @{$info->{technology}{pc}} ) {

    next if $pc->{name} !~ /^$host$/;
    next if $pc->{name} !~ /^$notes$/;

  print "$pc->{name} => $pc->{url} ($pc->{ip})\n";
for my $user ( @{$pc->{user}} ) {
  print "\t$user->{name} : $user->{password}\n";
        }
                        }

alguien me puede ayudar
Mensaje Vie Jun 06, 2008 6:42 pm
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4104
Ubicación: Valladolid, España
Responder citando

Te has equivocado. No es
Perl:
my $notes = $name || '.+';


sino
Perl:
my $notes = $notes || '.+';


Y no es
Perl:
next if $pc->{name} !~ /^$notes$/;


sino
Perl:
next if $pc->{notes} !~ /^$notes$/;


Falta, además, al principio, un
Perl:
our $notes;
Publicar nuevo tema   Responder al tema    Foros de discusión -> Intermedio Todas las horas son GMT - 6 Horas
Ir a página 1, 2, 3, 4  Siguiente
Página 1 de 4



Powered by phpBB © 2001, 2005 phpBB Group