Homepage Inspire-world | Forum
CGI/Perl Workshops Datendateien auslesen und darstellen

 Inhaltsverzeichnis/Workshops Übersichtsseite/Datendateien auslesen und darstellen
In diesem Workshop geht es darum eine Datendatei einzulesen und diese Daten so aufzuteilen das eine komplette Tabelle entsteht und das der zweite Teil des Datensatzes in Unterkategorienlinks aufgeteilt wird.

Bei der Tabellendarstellung sollen hier nicht einfach nur die Felder berücksichtigt werden die vorhanden sind, es sollen auch am Tabellenende Felder "aufgefüllt" werden mit leeren Tabellenzellen.

1. Hier zunächst die Beispielhafte Datendatei und das komplette Script

1. Die auszulesende Datendatei:
So ein Datenformat kann man benötigen um wie hier im Beispiel zu einer Hauptkategorie Unterkategorien darzustellen.
Autos|Autos---LKW---Fahrrad---Mofa
Computer|Computer---Festplatten---Graka---Monitore
Stellenanzeigen|Stellenangebote
Stellengesuche|Stellengesuche
Flohmarkt|Flohmarkt
Haushalt|Haushaltwaren---Technische Geraete---Moebel
Literatur|Romane---Fachbuecher---Lexika---Historisches
Haustiere|Hunde---Katzen---Voegel---Exoten---Fische
Dienstleistungen|Dienstleistungen aller Art
Reisen|Reisen---Hotels---Gaststaetten---Sehenswertes---Freizeitparks
Homepages|Allgemein---Grafik---Programierung---Computer---Hardware---Software---Betriebssysteme
2. Das komplette Script:
Hinweis! Ich habe in diesem Beispiel die Ausgabe einer Tabelle mit 2 und 3 Spalten zusammengefasst.
#!/usr/bin/perl

#Fehlerausgabe an Browser

use CGI::Carp qw(fatalsToBrowser);

# Zeichen vor Topkategorie Name
$zvt ="•";

# Zeichen vor Unterkategorie Name
$zvu ="<b>&#187;</b>";

# Script URL
$scripturl ="http://www.inspire-net.de/cgi-bin/htmtab";

header();

open(CAT,"cat.txt");
@kat = <CAT>;
close(CAT);

# - - - - - - - - - - - - - - - - - - - - - - - - - - #
# Tabelle mit zwei Spalten ausgeben
# - - - - - - - - - - - - - - - - - - - - - - - - - - #

print qq~
<table cellspacing="2" cellpadding="2" border="0" width="600">
<tr><td colspan="2"><b>Kategorien</b></td></tr>
~;


$zahl = 0;
@kat = sort @kat;
foreach  $kateg (@kat) {
chomp(@kat);
($kattitel,$katdesc) = split(/\|/, $kateg);
$zahl++;

if ($zahl == 1) {
print "<tr>\n<td width=\"50%\">$zvt<b> $kattitel</b><br>";

ukat();

print "</td>\n";
}
if ($zahl == 2) {
print "<td width=\"50%\">$zvt<b> $kattitel</b><br>";

ukat();

print "</td></tr>\n";
$zahl = 0;
}
}

if ($zahl == 1) {
print"<td width=\"50%\"> </td>\n</tr>\n";
print "</table><br>\n";
} 
if  ($zahl == 0) {
print "</table><br>\n";
}

# - - - - - - - - - - - - - - - - - - - - - - - - - - #
# Tabelle mit drei Spalten ausgeben
# - - - - - - - - - - - - - - - - - - - - - - - - - - #


print qq~

<table cellspacing="2" cellpadding="2" border="0" width="600">
<tr><td colspan="3"><b>Kategorien</b></td></tr>

~;
my $zahl2 = 0;
foreach $kateg (@kat) {
chomp(@kat);
($kattitel,$katdesc) = split(/\|/, $kateg);
$zahl2++;

if ($zahl2 == 1) {
print "<tr>\n<td width=\"33%\">$zvt<b> $kattitel</b><br>";

ukat();


print "</td>\n";
}
if ($zahl2 == 2) {
print"<td width=\"33%\">$zvt<b> $kattitel</b><br>";

ukat();

print "</td>\n";
}
if ($zahl2 == 3) {
print"<td width=\"33%\">$zvt<b> $kattitel</b><br>";

ukat();

print "</td>\n</tr>\n";
$zahl2 =0;
}
}

if ($zahl2 == 1) {
print"<td width=\"33%\"> </td><td width=\"33%\"> </td>\n</tr>\n";
print "</table><br>\n";
}
if ($zahl2 == 2) {
print"<td width=\"33%\"> </td>\n</tr>\n";
print "</table><br>\n";
} 
if  ($zahl2 == 0) {
print "</table><br>\n";
}
footer();
# - - - - - - - - - - - - - - - - - - - - - - - - - - #
# Unterkategoriensubroutine
# - - - - - - - - - - - - - - - - - - - - - - - - - - #
sub ukat {
@katdesc = $katdesc;
@katdesc = split('---', $katdesc);
@katdesc = sort @katdesc;
$anzahl = @katdesc;

for ( $i = 0; $i+1 <= $anzahl; $i++ ) {
print " $zvu <a href=\"$scripturl/view.pl?name=$katdesc[$i]\">$katdesc[$i]</a> ";
}
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - #
# Seitenheader
# - - - - - - - - - - - - - - - - - - - - - - - - - - #
sub header {
print "Content-type: text/html\n\n";

print qq~
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<html>
<head>
<META http-equiv="Content-Type" content="text/html">
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">

<title>Tabellenausgabe</title>
<style type="text/css">
a { 
font: 11px Verdana,Arial;
text-decoration: none;
}
a:hover { 
font: 11px Verdana,Arial;
text-decoration: underline overline;
background: #ffffff;
}

td {
font: 12px Verdana,Arial;
vertical-align: top;
border: 1px solid #477b9a;
background: #dee7ef;
}

table {
border: 1px solid #46628c;
background: #dee7ef;
}


</style>
</head>
<body><div align="center">
~;
}

# - - - - - - - - - - - - - - - - - - - - - - - - - - #
# Seitenfooter
# - - - - - - - - - - - - - - - - - - - - - - - - - - #
sub footer {
print qq~
</div>
</body>
</html>
~;
}
3. Dies ist die Ausgabe die obiges Script erzeugt

Screenshot der Scriptausgabe


2. Das Script mit den Erläuterungen zu den einzelnen Abschnitten
Ich habe hier alle Erläuterungen als Kommentar direkt in den Code notiert.
#!/usr/bin/perl

# Fehlerausgabe an Browser
# Diese Zeile sollte nicht fehlen
use CGI::Carp qw(fatalsToBrowser);

# Die Nachfolgenden 2 Variablen sind die Aufzählungszeichen 
# Die vor den Haupt,- und Unterkategorien angezeigt werden
# Zeichen vor Topkategorie Name
$zvt ="&#149;";

# Zeichen vor Unterkategorie Name
$zvu ="<b>&#187;</b>";

# Der Script URL zu dem Scriptverzeichnis
$scripturl ="http://www.inspire-net.de/cgi-bin/htmtab";

# Den Scriptheader aus der Subroutine aufrufen
# Subroutinen können mit und ohne & vor dem Subroutinen
# Aufruf notiert werden.
header();

# Öfnen und auslesen der Kategoriendatei in das Array @kat
open(CAT,"cat.txt");
@kat = <CAT>;
close(CAT);

# - - - - - - - - - - - - - - - - - - - - - - - - - - #
# Tabelle mit zwei Spalten ausgeben
# - - - - - - - - - - - - - - - - - - - - - - - - - - #

# Hier wird in in einem print qq Bereich der Tabellenkopf ausgegeben

print qq~
<table cellspacing="2" cellpadding="2" border="0" width="600">
<tr><td colspan="2"><b>Kategorien</b></td></tr>
~;

# Nun folgt der Bereich in dem die eigentliche
# Tabellenaufbauarbeit geleistet wird.
# Zähler auf 0 setzen 
$zahl = 0;
# Sortieren mittels sort
@kat = sort @kat;
# Durchlaufen der Datensätze mittels einer foreach Schleife
foreach  $kateg (@kat) {
chomp(@kat);
# Splitten der Werte pro Zeile
($kattitel,$katdesc) = split(/\|/, $kateg);
# Zähler pro Zeile um 1 erhöhen
$zahl++;

# If Abfrage des Zählerstandes, ist dieser 1 dann
# Ausgabe der ersten Spalte der Tabelle
if ($zahl == 1) {
print "<tr>\n<td width=\"50%\">$zvt<b> $kattitel</b><br>";

# Aufrufen der Subroutine ukat 
# Diese splittet die Werte von $katdesc auf und stellt diese dar
ukat();

# Ausgabe Tabellenzellenende
print "</td>\n";
}

# If Abfrage des Zählerstandes, ist dieser 2 dann
# Ausgabe der zweiten Spalte der Tabelle
if ($zahl == 2) {
print "<td width=\"50%\">$zvt<b> $kattitel</b><br>";

# Aufrufen der Subroutine ukat 
# Diese splittet die Werte von $katdesc auf und stellt diese dar
ukat();

# Tabellenzellenende der zweiten Spalte ausgeben
print "</td></tr>\n";

# Hier wird der Zähler wieder auf 0 gesetzt und
# das ganze beginnt von vorn
$zahl = 0;
}
}


# Hier nun wird der Rest der Tabelle zusammengesetzt
# Das if ($zahl == 1) bewirkt das bei einem Zählerstand von 1
# eine leere letzte Tabellenzelle ausgegeben wird und
# und die Tabelle geschlossen wird
if ($zahl == 1) {
print"<td width=\"50%\"> </td>\n</tr>\n";
print "</table><br>\n";
} 

# Ist der Zähler jedoch 0 dann
# wird nur die Tabelle geschlossen
if  ($zahl == 0) {
print "</table><br>\n";
}

# - - - - - - - - - - - - - - - - - - - - - - - - - - #
# Tabelle mit drei Spalten ausgeben
# - - - - - - - - - - - - - - - - - - - - - - - - - - #

# Hier ist das selbe Beispiel wie oben, nur
# das hier eine Tabelle mit 3 Spalten ausgegeben wird

print qq~

<table cellspacing="2" cellpadding="2" border="0" width="600">
<tr><td colspan="3"><b>Kategorien</b></td></tr>

~;
my $zahl2 = 0;
foreach $kateg (@kat) {
chomp(@kat);
($kattitel,$katdesc) = split(/\|/, $kateg);
$zahl2++;



if ($zahl2 == 1) {
print "<tr>\n<td width=\"33%\">$zvt<b> $kattitel</b><br>";

ukat();

print "</td>\n";
}
if ($zahl2 == 2) {
print"<td width=\"33%\">$zvt<b> $kattitel</b><br>";

ukat();

print "</td>\n";
}

# Der Unterschied ist hier das der Zähler bis 3 geht 
# da es ja auch 3 Spalten darzustellen gilt.
if ($zahl2 == 3) {
print"<td width=\"33%\">$zvt<b> $kattitel</b><br>";

ukat();

print "</td>\n</tr>\n";
$zahl2 =0;
}
}

# Der restliche Tabellenaufbau ist analog zum Beispiel mit
# der Tabelle mit den zwei Spalten. Nur hier kann es ja sein das 
# am Ende zwei leere Spalten auszugeben sind...
if ($zahl2 == 1) {
print"<td width=\"33%\"> </td><td width=\"33%\"> </td>\n</tr>\n";
print "</table><br>\n";
}

# ... oder nur eine
if ($zahl2 == 2) {
print"<td width=\"33%\"> </td>\n</tr>\n";
print "</table><br>\n";
} 

# ... oder nur das Tabellenende
if  ($zahl2 == 0) {
print "</table><br>\n";
}

# Ausgabe der Subroutine footer
footer();
# - - - - - - - - - - - - - - - - - - - - - - - - - - #
# Unterkategoriensubroutine
# - - - - - - - - - - - - - - - - - - - - - - - - - - #

# Diese Subroutine die innerhalb jeder Tabellenzelle die Werte
# enthält aufgerufen wird tut folgendes:

sub ukat {
# 1. Aus $katdesc wird ein Array @katdesc 
# So einfach ist das tatsächlich mit dem
# wechsel von einer Variablen zum Array

@katdesc = $katdesc;

# 2. Hier wird das nun wieder gesplittet
# Wobei das Trennzeichen natürlich auch ein völlig anderes sein kann.
@katdesc = split('---', $katdesc);

# 3. Etwas Sortierung
@katdesc = sort @katdesc;

# 4. Will man die Anzahl Elemente eines Arrays herausfinden
# reicht es das so zu notieren, $anzahl kann dabei auch anders benannt
# werden ( $anzahl_kat, $zahlkat usw. usf.)
$anzahl = @katdesc;

# 5. Die Ausgabe der einzelnen Arrayelemente
# Hier wird mittels einer for Schleife und einer Zählvariablen $i
# Die Anzahl der vorhandenen Arrayelemente dargestellt.

# Das $i+1 wird benötigt um die Zahl von $anzahl mit 1
# beginnen zu lassen. Denn wenn $anzahl z.B. 4 zurückgibt und der
# Zähler $i = 0; ist dann wurde am Ende 5 statt 4 Elemente ausgegeben.

# Mit $i = 1; kann man aber nicht beginnen da ansonsten das erste Arrayelemment
# übersprungen würde. Das nächste wäre ja dann bereits Element zwei.

# $i++ zählt dann solange bis $i+1 <= $anzahl; ( <= bedeutet kleiner, gleich) ist.
for ( $i = 0; $i+1 <= $anzahl; $i++ ) {

# Fast geschafft...
# Auf Arrayelemente greift man mit $variable[Zahl] zu ( z.B. $katdesc[1])
# Da wir oben die Zählvariable $i benutzt haben werden diese dann hier
# auch mit dieser Zählvariable durchgezählt
print " $zvu <a href=\"$scripturl/view.pl?name=$katdesc[$i]\">$katdesc[$i]</a> ";
} # Ende der for Schleife

} # Ende der Subroutine
# - - - - - - - - - - - - - - - - - - - - - - - - - - #
# Seitenheader
# - - - - - - - - - - - - - - - - - - - - - - - - - - #
sub header {

# Die folgenden zwei Subroutinen geben den Header und Footer aus.
# Wobei die wichtigste Zeile hier diese "print "Content-type: text/html\n\n";"
# ist, die den Ausgabetyp des Dokumentes festlegt.

print "Content-type: text/html\n\n";

print qq~
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<html>
<head>
<META http-equiv="Content-Type" content="text/html">
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">

<title>Tabellenausgabe</title>
<style type="text/css">
a { 
font: 11px Verdana,Arial;
text-decoration: none;
}
a:hover { 
font: 11px Verdana,Arial;
text-decoration: underline overline;
background: #ffffff;
}

td {
font: 12px Verdana,Arial;
vertical-align: top;
border: 1px solid #477b9a;
background: #dee7ef;
}

table {
border: 1px solid #46628c;
background: #dee7ef;
}


</style>
</head>
<body><div align="center">
~;
}

# - - - - - - - - - - - - - - - - - - - - - - - - - - #
# Seitenfooter
# - - - - - - - - - - - - - - - - - - - - - - - - - - #
sub footer {
print qq~
</div>
</body>
</html>
~;
}


 Zum Inhaltsverzeichnis/Workshops Übersichtsseite/Datendateien auslesen und darstellen
Autor: Helmut Walter Homepage Inspire-world Fragen, Anregungen und Hinweise bitte in das Forum

Valid HTML 4.0! Valid CSS!