Die Kennungen der sprachabhängigen Texte in den Dateien
sind geändert. Zu den sprachabhängigen Texten gehören die Monatsnamen. In den Kalendergrunddaten-Dateien DOCROOT
/local/local.xml.LANG
.
und DOCROOT
/kal/b/YEAR
/COUNTRY
.xml.
stehen aber noch die alten Kennungen. Sie müssen durch die neuen Kennungen ersetzt werden. Wegen dieses Fehlers fehlen die Monatsnamen in den Kalendern.DOCROOT
/kal/b/YEAR
/a.xml.LANG
.
Dazu benutze ich ein Perl-Skript.
Die alten Kennungen werden in jeder Grunddaten-Datei benutzt. Ich lese sie aus der Datei
. Die Platzhalter sind in der Form DOCROOT
/kal/b/2020/de.xml.<l:ph id="
in der Datei enthalten. Die Datei enthält die Kalenderdaten nicht nur für das aktuelle Jahr, sondern auch für den Dezember des Vorjahres und den Januar des Folgejahres. Die Daten für jeden Monat enthalten den Platzhalter für den Monatsnamen meist mehrfach. Der folgende Perl-Code liest die alten Kennungen.ID
"/>
my $oldids = []; my $fn = "DOCROOT/kal/b/2020/de.xml."; my $verb = 1; my $h; if (!open ($h, "<", $fn)) { print STDERR "Kann Datei \"$fn\" nicht öffnen\n"; return; } my $d; { local $INPUT_RECORD_SEPARATOR; $d = <$h>; close $h; } my $pid = ""; my $id = ""; while ( $d =~ /<l:ph id="([a-z0-9]+)"\/>/g ) { $id = $1; if ($id ne $pid) { push (@$oldids, $id); $pid = $id; } } if ($verb) { $pid = 0; for $id (@$oldids) { print "$pid $id\n"; ++$pid; } }
Die Texte zu den Kennungen lese ich aus der Datei
mit den deutschen Texten. Sie sind in der Form DOCROOT
/local/local.xml.de.<t id="
enthalten. Ich speichere die Kennungen zu allen Texten als ID
">TEXT
</t>$newids -> {"
.TEXT
"} = "ID
"
my $newids = {}; $fn = "DOCROOT/local/local.xml.de."; $h = undef; if (!open ($h, "<:encoding(utf-8)", $fn)) { print STDERR "Kann Datei \"$fn\" nicht öffnen\n"; return; } { local $INPUT_RECORD_SEPARATOR; $d = <$h>; close $h; } # <t id="cr">Januar</t> while ( $d =~ /<t id="([a-z0-9]+)">([^>]+)<\/t>/g ) { $newids -> {$2} = $1; } my $names = [ "Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember", ], if ($verb) { my $nm; my $i = 0; for $nm (@$names) { ++$i; print "$i $nm ", $newids -> {$nm}, "\n"; } }
Nun ordne ich die neuen Kennungen den alten Kennungen zu in der Form $idmap -> {"
.OLD_ID
"} = "NEW_ID
"}
Der erste Eintrag in der Liste der alten Kennungen ist die Kennung für den Namen des Monats Dezember des Vorjahres. Ich ignoriere diesen Eintrag. Die nächsten zwölf Listeneinträge sind die Kennungen der Namen der Monate von Januar bis Dezember. Die Zuordnung ist einfach:
my $idmap = {}; shift @$oldids; my $nm; while (@$names) { $nm = shift @$names; $id = shift @$oldids; $idmap -> {$id} = $newids -> {$nm}; }
Ich erstelle jetzt eine Funktion, die in einer Kalenderdaten-Datei die alten Kennungen durch die neuen Kennungen ersetzt. Ein regulärer Ausdruck findet alle Platzhalter der Form <l:ph id="
. Die alte ID
"/>ID
ist die erste Match-Gruppe $1
des regulären Ausdrucks. Eine Hilfsfunktion liefert den Platzhalter mit der neuen ID: <l:ph id="
. Eine alte Kennung, der nicht eine neue Kennung zugeordnet ist (also kein Monatsname), bleibt stehen.NEWID
"/>
my $subst = sub { $id = $idmap -> {$1} || $1; return "<l:ph id=\"$id\"/>"; };
Die Funktion zur Verarbeitung einer Datei nimmt zwei Parameter: $in
ist der Dateipfad der Eingabedatei mit den alten Kennungen, $out
ist der Dateipfad der Ausgabedatei mit den neuen Kennungen.
my $proc_file = sub { my ($in, $out) = @_; print "$in -> $out\n" if $verb; $h = undef; if (!open ($h, "<:encoding(utf-8)", $in)) { print STDERR "Kann Datei \"$in\" nicht öffnen\n"; return; } { local $INPUT_RECORD_SEPARATOR; $d = <$h>; close $h; } $d =~ s/<l:ph id="([a-z0-9]+)"\/>/$subst -> ($idmap, $1)/ge ; $h = undef; if (!open ($h, ">:encoding(utf-8)", $out)) { print STDERR "Kann Ausgabedatei \"$out\" nicht öffnen\n"; return; } print $h $d; close $h; };
Alle Grunddaten-Dateien
und DOCROOT
/kal/b/YEAR
/COUNTRY
.xml.
sind zu korrigieren. Für die korrigierten Dateien wähle ich statt DOCROOT
/kal/b/YEAR
/a.xml.LANG
.
ein anderes Pfad-Präfix (DOCROOT
/kal/b
. Ich lese das Verzeichnis DOCROOT
/kal/bnew
und die Unterverzeichnisse DOCROOT
/kal/b
und verarbeite die Grunddaten-Dateien:YEAR
use File::Spec::Functions qw(catdir catfile); use File::Path qw(make_path); my $indir = "DOCROOT/kal/b"; my $outdir = "DOCROOT/kal/bnew"; my ($dh, $sdh); my ($de, $sde); my $dp; my $od; opendir ($dh, $indir); while (defined ($de = readdir ($dh))) { next unless $de =~ /^20\d\d$/; $dp = catdir ($indir, $de); next unless -d $dp; $sdh = undef; opendir ($sdh, $dp) $od = catdir ($outdir, $de); make_path ($od); while (defined ($sde = readdir ($sdh))) { next unless $sde =~ /\.xml(?:\..+)?\.$/; $proc_file -> (catfile ($dp, $sde), catfile ($od, $sde)); } closedir $sdh; } closedir $dh;
Zu jeder Grunddaten-Datei füge ich eine gzip-komprimierte Datei hinzu mit dem Suffix .gz
. Dazu benutze ich ein bash-Skript:
#!/bin/bash b=$(realpath $0); b=${b%/src/*}; dir=$b/docroot/kal/bnew; for sd in $dir/*; do echo "subdir $sd"; f=${sd#$dir/}; [[ $f =~ ^20[0-9][0-9]$ ]] || continue; [[ -d $sd ]] || continue; for f in $sd/*xml*\. ; do echo $f; gzip --best --stdout $f > ${f}gz ; done; done;
Die vollständigen Skripte sind monidfix.pl
(Quelltext) und monidfix_addgz
.