Mam plik XML, który muszę przenieść do listy za pomocą Perla (bez użycia XSLT).
To jest mój (uproszczony, usunięty jak 10 dodatkowych atrybutów, aby ułatwić czytanie!) XML:
...
<XMLTAG ID="1" name="NAME1" status="0" date1="24.05.2012 13:37:00" date2="25.05.2012 13:37:00" />
<XMLTAG ID="2" name="NAME2" status="1" date1="24.05.2012 13:37:00" date2="25.05.2012 13:37:00" />
<XMLTAG ID="3" name="NAME3" status="0" date1="24.05.2012 13:37:00" date2="25.05.2012 13:37:00" />
...
Co mam do tej pory:
my $input = in.xml;
my $output = out.txt;
# open input
open( INPUT, $input )
|| die "Can"t find $input: $_";
# open output
open( OUTPUT, ">$output" )
|| die "Can"t find $output: $_";
# run until perl returns undef (at the end of the file)
while (<INPUT>) {
if ($_ == /date1="[0-3]?[0-9].[0-3]?[0-9].(?:[0-9]{2})?[0-9]{2} [0-5][0-9]:[0-5][0-9]:[0-5][0-9]"/) {
print OUTPUT $_;};
}
close(INPUT);
close(OUTPUT);
Plik wyjściowy powinien wyglądać następująco:
date1="24.05.2012 13:37:00"
date1="24.05.2012 13:37:01"
date1="24.05.2012 13:37:02"
...
Z góry dziękuję, Marley
Odpowiedzi:
6 dla odpowiedzi № 1use XML::LibXML qw();
my $dom = XML::LibXML->load_xml(location => "in.xml");
printf qq(date1="%s"n), $_->getAttribute("date1")
for $dom->findnodes("//XMLTAG");
1 dla odpowiedzi nr 2
Powinieneś użyć odpowiedniego modułu analizującego XML. Istnieje wiele dostępnych, ale oto rozwiązanie wykorzystujące XML::Smart
.
Nie wybrałbym tego rozwiązania, ale chciałbym wiedzieć, dlaczego odpisałeś XSLT?
use strict;
use warnings;
use XML::Smart;
my $input = "in.xml";
my $output = "out.txt";
open my $out, ">", $output or die qq(Can"t open output file "$output": $!);
my $xml = XML::Smart->new($input);
my $text = $xml->{root}{XMLTAG};
my $xmltags = $xml->{root}{XMLTAG};
for my $tag (@$xmltags) {
print $out qq(date1="$tag->{date1}"n);
}
wydajność
date1="24.05.2012 13:37:00"
date1="24.05.2012 13:37:00"
date1="24.05.2012 13:37:00"
1 dla odpowiedzi nr 3
Za pomocą XML :: XSH2:
open in.xml ;
ls //@date1 ;
0 dla odpowiedzi nr 4
Możesz użyć nie chciwego dopasowania, takiego jak to:
if ($_ =~ /(date1=".*?")/ ) {
print OUTPUT "$1n";
}
0 dla odpowiedzi № 5
próbować:
date1="(.*?)"
dla wyrażenia regularnego wyszukiwanie nie będzie zachłanne.
AKTUALIZACJA:
ostrzegają mnie, że nie ma potrzeby unikania podwójnych cytatów, więc
date1="(.*?)"
zrobi.