Por favor, por favor - não use uma solução baseada em expressões regulares, como awk
ou sed
.
XML
é contextual, em que expressões regulares não são - para que eles NUNCA funcionem corretamente, eles são apenas um pouco hackeados .
Mas o XML tem uma solução para esse problema - ele é chamado de xpath
, que permite "pesquisar" de maneira contextual.
Então, para dar o seu exemplo:
#!/usr/bin/perl
use warnings;
use strict;
use XML::Twig;
my $xml = XML::Twig -> new -> parsefile('your_file.xml');
foreach my $wpt ( $xml -> get_xpath('//wpt') ) {
print join ",", $wpt -> att('lat'),
$wpt -> att('lon'),
$wpt -> first_child_text('time'), "\n";
}
O que dá o resultado desejado, mas também irá lidar com uma variedade de formas do seu XML perfeitamente idênticas e semanticamente válidas.
Como recuado:
<xml>
<wpt lat="1.345529841" lon="103.7577152">
<time>2010-01-01T00:00:00Z</time>
</wpt>
<wpt lat="1.345529841" lon="103.7577152">
<time>2010-01-01T00:00:00Z</time>
</wpt>
<wpt lat="1.3982529841" lon="103.90877152">
<time>2010-01-01T00:00:00Z</time>
</wpt>
</xml>
Tudo em uma única linha:
<xml><wpt lat="1.345529841" lon="103.7577152"><time>2010-01-01T00:00:00Z</time></wpt><wpt lat="1.345529841" lon="103.7577152"><time>2010-01-01T00:00:00Z</time></wpt><wpt lat="1.3982529841" lon="103.90877152"><time>2010-01-01T00:00:00Z</time></wpt></xml>
Outro estilo de recuo:
<xml>
<wpt
lat="1.345529841"
lon="103.7577152">
<time>2010-01-01T00:00:00Z</time>
</wpt>
<wpt
lat="1.345529841"
lon="103.7577152">
<time>2010-01-01T00:00:00Z</time>
</wpt>
<wpt
lat="1.3982529841"
lon="103.90877152">
<time>2010-01-01T00:00:00Z</time>
</wpt>
</xml>
Ou até mesmo:
<xml
><wpt
lat="1.345529841"
lon="103.7577152"
><time
>2010-01-01T00:00:00Z</time></wpt><wpt
lat="1.345529841"
lon="103.7577152"
><time
>2010-01-01T00:00:00Z</time></wpt><wpt
lat="1.3982529841"
lon="103.90877152"
><time
>2010-01-01T00:00:00Z</time></wpt></xml>
Todos são semanticamente idênticos e devem ser analisados da mesma maneira. Espero que esteja bastante claro que uma expressão regular para fazer isso é MUITO mais complicada do que apenas usar um analisador XML.
Para ser conciso:
perl -MXML::Twig -0777 -e 'XML::Twig->new(twig_handlers=>{wpt=>sub{print join ",", $_->att("lat", $_->att("lon"),$_->first_child_text("time"), "\n" }})->parse(<>)'