Automatisierter Aufruf des W3C-Validators

Automatisierter Aufruf des W3C-Validators

Ob nun aus Kosten-, Bandbreiten- oder anderen Gründen: Es ist vorteilhaft, wenn man seine (X)HTML-Dokumente vor dem Hochladen auf den Server ohne viel Mühe "in einem Rutsch" validieren und/oder auf Wohlgeformtheit überprüfen kann.

Viele werden ohnehin eine Version des W3C-Validators lokal installiert haben. Wer nicht, findet sicher in folgenden Aneitungen, was er sucht:

Für diejenigen, welche keine Hinweise benötigen oder wollen:

Hinweis: Nutzer von Betriebssystemen oder Rechnerplattformen, welche nicht ein einzelnes "Newline" als Zeilenumbruch benutzen, laden sich am besten die .zip oder .gz Version herunter und überlassen dem Packprogramm die Konvertierung der Zeilenumbrüche.

Download
checkhtml.pl (4521 Bytes), checkhtml.pl.gz (1875 Bytes), checkhtml.zip (2000 Bytes)
Listing
Listing auf dieser Seite

Hinweise, Funktionsweise

Benötigte Module

Genutzt werden die Module LWP::UserAgent sowie HTTP::Request::Common. Diese Module sind Teil der Standard-Distributionen von Perl und werden auch für den Betrieb des W3C-Validators benötigt.

Validierung über die URI

Diese Möglichkeit bietet sich an, wenn die zu testenden Seiten auch über den lokalen Webserver erreichbar sind. Die Adresse der zu testenden Seite wird dabei als Parameter bei der GET-Anfroderung an den Validator übergeben und dieser holt sich die Seite selbst von der angegebenen Adresse.

Auf diese Weise kann auch eine Kopie der lokalen Dateien auf einem Server online getestet werden. Dazu müssen nur die Variablen für den "lokalen" Server ($localserv) und für das entsprechende Startverzeichnis ($localw3dir) entsprechend gesetzt werden.

Validierung per Upload

Sollten die Seiten nicht über den lokalen oder einen anderen Webserver erreichbar sein, können sie auch via Upload an den Validator übermittelt werden. Die zu validierende Seite wird dabei über eine POST-Anforderung zusammen mit dem Dateiinhalt an den Validator übermittelt.

Hinweis: Sollten die Dokumente keine zum Content-Type- und/oder Charset-Header äquivalente Informationen (wie etwa entsprechende Meta-Angaben im HEAD-Element oder eine XML-Deklaration enthalten), obwohl diese notwendig sind und diese Angaben sonst durch den Webserver geliefert werden, kann der Validator u.U. nicht richtig arbeiten.

Anzupassende Variable und Einstellungen

Die erste Zeile...

... sollte den komplette Pfad zum ausführbaren Perl-Interpreter enthalten. Unter unix-artigen Systemen ist dies meist #!/usr/bin/perl -w oder #!/usr/local/bin/perl -w. Unter Windows könnte die erste Zeile #!C:/perl/bin/perl.exe -w lauten.

$upload

Bei einem Wert von 0 wird das zu überprüfende Überprüfende Dokument via URI übermittelt, siehe Validierung über die URI. Ist der Wert gleich 1 (bzw. im Moment ungleich 0), erfolgt die Übermittlung des Dokumentes per Upload zum Validator, siehe auch Validierung per Upload.

$releasedir

Enthält den absoluten (vollständigen) Pfad zu den lokalen Dokumenten. Das Slash ("/") am Ende nicht vergessen! Beispiel: C:/Eigene Dateien/www/testsite/

$localw3dir

Der absolute (vollständige) Pfad zu den Dokumenten auf dem (lokalen) Webserver. Das Slash ("/") am Ende nicht vergessen! Beispiel: /, /~dirk/ oder /users/dirk/

$localserv

Protokoll und Rechnername des (lokalen) Webservers. Angabe ohne abschließendes Slash ("/"). Beispiel: http://localhost oder http://intranet.nonamenoip.de.

$validator

URI zum Validierungsprogramm des Validators. Beispiel: http://validator.w3.org/check oder http://validator.meinname.de/check

$cr

Enthält die auf dem System gültige Zeichenkombination für einen Zeichenumbruch. Unix: \n, DOS, Windows: \n\r, Mac: \r

$quiet

Wenn der Wert gleich 0 ist, werden keine Meldungen über Fortschritt und Ergebnisse der Prüfung der Dokumente ausgegeben. Bei einem Wert gleich 1 (im Moment ungleich 0) werden Meldungen ausgegeben. Beispielmeldung:

Beginn processing
-----

Processing directory /exports/www/club2/users/dirk/
 processing	callerid.html	o.k.	 done.
 processing	games.html	o.k.	 done.
 ...
 processing	index.html	Error	 done.
 processing	checkhtml.html	o.k.	 done.
 ...
Processing directory /exports/www/club2/users/dirk/dwnl/
 processing	index.html	o.k.	 done.
 ...
----
Finished: 29 files in 59 sec - 1 errors found.
$html_regex

Regulärer Ausdruck zum Erkennen von zu überprüfenden Dokumenten. Mit folgendem Ausdruck werden Dateien mit den Endungen .htm, .html, .shtm und .shtml erkannt: ^([a-z0-9\-\_\.]*?)\.s?html?$. Um beispielsweise auch noch Dokumente mit den Endungen .php* oder .cgi abzurufen, wäre folgender Ausdruck notwendig bzw. möglich: ^([a-z0-9\-\_\.]*?)\.(s?html?|php.?|cgi)$.

$useragent

Eine Kennung für den User-Agent der bei Abruf von Seiten als http-Header übermittelt wird. Eine Angabe von W3C_Validator/local führt zu einem Eintrag wie beispielsweise "W3C_Validator/local (libwww-perl/5.50)" in den Logbüchern eines Webservers. Praktisch, wenn man eigene Zugriffe aus den Statistiken herausfiltern will und den User-Agent-Header nicht fälscht oder unterdrückt,

Weiter Möglichkeiten und Hinweise

Das Script



#!/usr/bin/perl -w 
##
## This program is free software; you can redistribute it
## and/or modify it under the terms of the GNU General
## Public License as published by the Free Software Foundation
## (http://www.gnu.org/); either version 2 of the License, or
## (at your option) any later version.
##
## Author : Dirk Steinchen (dirk@atelier89.de)
## Webpage: http://www.atelier89.de/users/dirk/html/validator.html
## Version: 1.0

use strict;
use LWP::UserAgent;
use HTTP::Request::Common;

## edit this to your needs
    ## upload (post) files or get validation results
    ##  via uri? 0=uri, 1=upload
    my $upload = 0;
    ## absolute path to your local html files
    ##  e.g. '/exports/www/testsite/' or 'c:/www/testsite/'
    ##  don't forget the "/"
    my $releasedir = '/exports/www/testsite/';
    ## absolute path to your files on local www-server
    ##  e.g. '/testsite/' don't forget the "/"
    my $localw3dir = '/testsite/';
    ## your local www-server
    ##  don't insert the "/"
    my $localserv = 'http://localhost';
    ## the validator listens here
    my $validator = 'http://validator.w3.org/check';
    ## use "\n\r" for DOS/Win and "\n" for unix-like OS, "\r" for MAC
    my $cr = "\n";
    ## Generate Output: 0=yes, 1=no
    my $quiet = 0;
    ## mask for files we test, actually *.htm and *.html
    my $html_regex = '^([a-z0-9\-\_\.]*?)\.html?$';
    ## name of the user-agent for testing, libwww version is appended later
    my $useragent = "W3C_Validator/local ";

## edit lines below this line shouldn't be needed
    ## error-counter
    my $errors = 0;
    ## file-counter
    my $files = 0;
    ## start-time
    my $time = time;

    print $cr, $cr, "Beginn processing", $cr, "-----", $cr if $quiet == 0;

    ## process (and recurse) the given directory
    process_directory($releasedir);
    ## statistics
    $time = time - $time;
    print "----", $cr, "Finished: $files files in $time sec" if $quiet == 0;
    print " - $errors errors found.", $cr, $cr if $quiet == 0;
    ## return 0 if no errors otherwise the error-count
    exit $errors;

sub process_directory {
    my $directory = $_[0];
    ## internal var's
    my (@subdir, @verzeichnis,
     $key, $content, $ua, $req, $data, $file);

    ## read current directory
    opendir (VERZEICHNIS, $directory) || die "$directory: $!".$cr;
     @verzeichnis = readdir (VERZEICHNIS);
    closedir (VERZEICHNIS);

    print $cr, "Processing directory $directory", $cr if $quiet == 0;

    ## process each entry in directory list
    foreach $key (@verzeichnis) {
     ## is current entry a html-file?
     if ($key =~ /$html_regex/i) {
         ## if so, process this entry
         print " processing\t$key\t" if $quiet == 0;
         $data = $directory;
         ## if errors found, they go in this file
         $file = $key.".err.html";
         ## create user-agent
         $ua = new LWP::UserAgent;
         ## user agent's name
         $ua->agent($useragent.$ua->agent);
         ## validation by uri oder upload?
         if ($upload == 0) {
          ## get the resource name on local www-server
          $data =~ s/$releasedir/$localw3dir/i;
          ## request for validation (get via uri)
          $req = new HTTP::Request (
                    GET=>"$validator?uri=$localserv$data$key");
         } else {
          ## request for validation (upload file)
          $req = POST "$validator",
              Content_Type => 'multipart/form-data',
              Content => [
               uploaded_file => [ "$data$key" ]
              ];
         }
         ## result of validation
         $content = $ua->request($req)->content;
         ## one more file...
         $files++;
         ## write result to file
         open (DATEI, "> $directory$file") || die $!;
          print DATEI $content;
         close (DATEI);
         ## valid/wellformed document?
         if ($content =~ /No errors found\!/) {
          ## if so, clean up
          print "o.k.\t" if $quiet == 0;
          unlink "$directory$file";
         }
         else {
          ## if document is not valid, inc error-counter
          ##  and leave file with results on disk
          $errors++;
          print "Error\t" if $quiet == 0;
         }
         ## that's it for this page
         print " done.$cr" if $quiet == 0;
        } else {
         ## if directory entry is a subdir
         if (-d "$directory$key") {
          ## save this entry for later processing
          push (@subdir, $key)
         }
     }
    }
    ## process subdir's in current directory
    foreach $key (@subdir) {
     ## process only entrys that not refer to
     ##  current (.) or upper (..) directory
     if (!($key =~ /^\.*$/)) {
         ## process subdirectory (and recursivly it's subdirectorys)
             process_directory ("$directory$key/");
     }
    }
}