Plik XML wygląda tak:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE lista.kompozycji SYSTEM "lkompc.dtd" >
<lista.kompozycji>
<kompozycja typ="i.orkiestro">
<tytul>Atlantyda I na orkiestrę symfoniczną</tytul>
<xsklad>4 akordeony w orkiestrze</xsklad>
<autor>
<nazwisko>Augustyn</nazwisko>
<imie>Rafał</imie>
</autor>
<rok>1979</rok>
<sklad>4 acc</sklad>
<wydawca>manus</wydawca>
</kompozycja>
...
<kompozycja typ="solo">
<tytul>Rapsodia</tytul>
<xsklad>akordeon solo</xsklad>
<autor>
<nazwisko>Krzanowski</nazwisko>
<imie>Andrzej</imie>
</autor>
<autor>
<nazwisko>Krzanowska</nazwisko>
<imie>Grażyna</imie>
</autor>
<rok>1983</rok>
<wydawca>PWM</wydawca>
<nagranie>KM</nagranie>
</kompozycja>
...
</lista.kompozycji>
a ma wyglądać tak:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE lista.kompozycji SYSTEM "lkompc.dtd" >
<lista.kompozycji>
<kompozytor id='Augustyn.R'><!-- *** Augustyn:Rafał# -->
<kompozycja typ="i.orkiestro">
<tytul>Atlantyda I na orkiestrę symfoniczną</tytul>
<xsklad>4 akordeony w orkiestrze</xsklad>
<rok>1979</rok>
<sklad>4 acc</sklad>
<wydawca>manus</wydawca>
</kompozycja>
<kompozycja typ="i.orkiestro">
<tytul>Atlantyda II na wielką orkiestrę i chór</tytul>
<xsklad>4 akordeony w orkiestrze</xsklad>
<rok>1983</rok>
<sklad>4 acc</sklad>
<wydawca>manus</wydawca>
<nagranie>LP</nagranie>
</kompozycja>
</kompozytor>
...
<kompozytor id='Krzanowski.A#Krzanowska.G'><!-- *** Krzanowski:Andrzej#Krzanowska:Grażyna# -->
<kompozycja typ="solo">
<tytul>Rapsodia</tytul>
<xsklad>akordeon solo</xsklad>
<rok>1983</rok>
<wydawca>PWM</wydawca>
<nagranie>KM</nagranie>
</kompozycja>
...
</lista.kompozycji>
To znaczy, że z elementu kompozycja
mają zniknąć elementy autor
. Wszystkie kompozycje tego samego kompozytora mają być elementami-dziećmi elementu kompozytor
. Element kompozytor
ma identyfikować kompozytora za pomocą atrybutu id
, którego wartość jest wyznaczana (w przypadku gdy dzieło jest ma jednego autora) jako:
nazwisko.inicjał
W przypadku gdy kompozycja jest dziełem zbiorowym, identyfikator kompozytora zbiorowego ma mieć postać:
nazwisko.inicjał#nazwisko.inicjał
nazwisko.inicjał#nazwisko.inicjał#nazwisko.inicjał ...
Powyższe realizuje taki oto skrypt:
#!/usr/bin/perl
use XML::DOM;
binmode(STDOUT, ":utf8");
my $file2parse = $ARGV[0];
my $parser = new XML::DOM::Parser;
my $doc = $parser->parsefile ($file2parse);
for my $kompozycja ( $doc->getElementsByTagName ("kompozycja") ) {
my $author_id = '';
## przeglądamy kolejne elementy autor:
for my $autor ($kompozycja->getElementsByTagName("autor")) {
$im = ($autor->getElementsByTagName("imie"))[0]->toString();
$nz = ($autor->getElementsByTagName("nazwisko"))[0]->toString();
$author_id .= "$nz:$im#"; ## autorów może być dużo stąd .= a nie =
$author_id =~ s/<[^<>]+>//g; ## usuń tagi, zostaw sam tekst
##print STDERR "$author_id\n";
## usuń element autor:
$kompozycja->removeChild($autor);
}
## Hash of Arrays, cf http://docstore.mik.ua/orelly/perl2/prog/ch09_02.htm
push @{ $Kompozycje{ $author_id }}, $kompozycja->toString ();
}
### Druk ############################################################
print "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
print "<!DOCTYPE lista.kompozycji SYSTEM \"lkompc.dtd\" >\n";
print "<lista.kompozycji>\n";
for $autor (sort keys %Kompozycje ) {
$autor_i = $autor;
$autor_i =~ s/:([^#:])[^#:]+#/.\1#/g; # tylko inicjały
chop($autor_i);
print "\n\n\n\n<kompozytor id='$autor_i'><!-- *** $autor -->\n\n";
for $kompozycja ( @{ $Kompozycje{ "$autor" }} ) {
print $kompozycja, "\n";
}
print "\n</kompozytor>\n";
}
print "</lista.kompozycji>\n";
## koniec ###
Jeżeli się nie doda binmode
, to UTF jest malformed (Ah ten Perl.) Podpowiedź znalazłem tutaj. Nawiasem mówiąc i w innym skrypcie:
s/<imie>([^<>])([^<>]+)<\/imie>/<inicjal>\1<\/inicjal>/gm;
Też zwraca malformed UTF-8 jeżeli np. imieniem jest Łukasz. A jak zaczyna się od A-Z to jest OK.
Brak komentarzy:
Prześlij komentarz