• Publicidad

Duda simple con XML::Simple

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Duda simple con XML::Simple

Notapor fgalves » 2007-10-31 05:42 @279

Hola a todos,

Tengo una duda que supongo que sabréis responder rápidamente.

Estoy trabajando con un fichero XML y con el modulo XML::Simple y tengo una pequeña duda.

Sintáxis: [ Descargar ] [ Ocultar ]
Using xml Syntax Highlighting
<PathElements>          
<Node1>
      <Path>__MDW_ROOT__/ProgressiveMigrations/__DB__/Lib</Path>
      <pkgname>ProgressiveMigrations</pkgname>
 </Node1>
<Node2>
      <Path>......</Path>
      <pkgname>....</pkgname>
</Node2>
.....
</PathElements>
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Mi duda es la siguiente: una vez que encuentro el valor de pkgname que deseo obtener, ¿cómo hago para obtener el nombre del nodo superior (Node1, Node2, ....)?
¿Hay alguna manera simple de hacerlo?

Gracias por adelantado,
Un saludo,
Felipe
fgalves
Perlero nuevo
Perlero nuevo
 
Mensajes: 210
Registrado: 2006-09-25 13:54 @621

Publicidad

Notapor explorer » 2007-10-31 06:24 @308

En caso de usar el XML::Simple...

Si estoy recorriendo los nodos NodeX, y en alguno de ellos encuentro el pkgname, entonces sí que sé en qué nodo estoy.
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

Como con XML::Simple o XML::Rules

Notapor Jenda » 2007-10-31 07:07 @338

No me parece bien proyectado este XML, pero quizás no es algo que tu puedes cambiar.

Con XML::Simple tienes que ver la estructura de datos que XMLin() produce y después usar un ciclo foreach visitando todos los NodeX:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my $XML = <<'*END*';
<PathElements>
<Node1>
      <Path>__MDW_ROOT__/ProgressiveMigrations/__DB__/Lib</Path>
      <pkgname>ProgressiveMigrations</pkgname>
 </Node1>
<Node2>
      <Path>......</Path>
      <pkgname>....</pkgname>
</Node2>
</PathElements>
*END*

use XML::Simple;

my $data = XMLin($XML);

#use Data::Dumper;
#print Dumper($data);

foreach my $node (keys %$data) {
        if ($data->{$node}{pkgname} eq 'ProgressiveMigrations') {
                print $node, "\n";
                last;
        }
}
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


El problema con esta solución es que ante todo parseas todo el XML produciendo una estructura que podría ser grande y después solo usas dos poquitas cosas de ella. Si el fichero es grande eso no es muy bueno. Con un módulo diferente es posible no tener que recordar todos los datos. Algo así:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
use XML::Rules;

{
        my ($look_for,$result);
        my $parser = XML::Rules->new(
                rules => [
                        pkgname => sub {
                                my ($tag,$attr,$context) = @_;
                                if ($attr->{_content} eq $look_for) {
                                        $result = $context->[1];
                                }
                                return;
                        },
                        _default => '',
                ],
        );

        sub buscaNodeConPkgname {
                $look_for = shift();
                $result = undef;
                $parser->parse($_[0]);
                return $result;
        }
}

print buscaNodeConPkgname('ProgressiveMigrations', $XML);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Este código no recuerda nada de este XML excepto del nombre del NodeX tag pero no para a parsear el XML después de encontrar el pkgname que estás buscando. El módulo aún no soporta dejar de parsear en medida del fichero así que el código es un poco más complejo:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
use XML::Rules;

{
        my ($look_for,$result);
        my $parser = XML::Rules->new(
                rules => [
                        pkgname => sub {
                                my ($tag,$attr,$context) = @_;
                                if ($attr->{_content} eq $look_for) {
                                        $result = $context->[1];
                                        die "Encontré que estuve buscando\n";
                                };
                                return;
                        },
                        _default => '',
                ],
        );

        sub buscaNodeConPkgname {
                $look_for = shift();
                $result = undef;
                eval {
                        $parser->parse($_[0]);
                };
                if ($@) {
                        if ($@ =~ /^Encontre que estuve buscando/) {
                                return $result;
                        } else {
                                die $@;
                        }
                } else {
                        return;
                }
        }
}

print buscaNodeConPkgname('ProgressiveMigrations', $XML);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


con XML::Rules 0.21 (aún no publicado!) sería más simple:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
{
        my ($look_for,$result);
        my $parser = XML::Rules->new(
                rules => [
                        pkgname => sub {
                                my ($tag,$attr,$context,$data,$parser) = @_;
                                if ($attr->{_content} eq $look_for) {
                                        $result = $context->[1];
                                        $parser->return_nothing();
                                };
                                return;
                        },
                        _default => '',
                ],
        );

        sub buscaNodeConPkgname {
                $look_for = shift();
                $result = undef;
                $parser->parse($_[0]);
                return $result;
        }
}

print buscaNodeConPkgname('ProgressiveMigrations', $XML);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Jenda
P.S.: Perdona mi español por favor.
P.P.S.: Gracias por darme una idea para XML::Rules. No se me ha ocurrido antes que podría ser útil dejar de parsear el fichero antes del fin.
Jenda
Perlero nuevo
Perlero nuevo
 
Mensajes: 132
Registrado: 2007-10-29 06:31 @313
Ubicación: Praga, Republica Checa


Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado

cron