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:
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í:
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:
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:
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.