Felix Riesterer: DOMDocument - mit HTML5-Parser

Beitrag lesen

Lieber molily,

Besser einen vollwertigen HTML5-Parser verwenden, wenn möglich:
http://masterminds.github.io/html5-php/

mit viel Mühe habe ich das Teil ohne Composer nun in mein Projekt integriert. Die Klasse wird korrekt inkludiert. Das war ein Stück Arbeit!

Nun konnte ich mit diesem Parser etwas experimentieren... und stelle fest, er erstellt ein hundsgewöhnliches DOMDocument. Inwiefern bin ich nun besser dran? Dahingehend, dass das DOM nach dem Parsen "garantiert" im Sinne des Browsers erstellt wurde und eben nicht nach den Regeln in libxml2? Hmm. War das die Arbeit wert?

Meine Lösung ohne jedwelchen Composer oder so:

// load HTML5 Parser (my dir: ./base/html5.lib)  
$files = array(  
    // diese Einträge werden eigentlich dynamisch generiert  
    './base/html5.lib/HTML5/Parser/CharacterReference.php',  
    './base/html5.lib/HTML5/Parser/DOMTreeBuilder.php',  
    './base/html5.lib/HTML5/Parser/EventHandler.php',  
    './base/html5.lib/HTML5/Parser/FileInputStream.php',  
    './base/html5.lib/HTML5/Parser/InputStream.php',  
    './base/html5.lib/HTML5/Parser/ParseError.php',  
    './base/html5.lib/HTML5/Parser/Scanner.php',  
    './base/html5.lib/HTML5/Parser/StringInputStream.php',  
    './base/html5.lib/HTML5/Parser/Tokenizer.php',  
    './base/html5.lib/HTML5/Parser/TreeBuildingRules.php',  
    './base/html5.lib/HTML5/Parser/UTF8Utils.php',  
    './base/html5.lib/HTML5/Serializer/HTML5Entities.php',  
    './base/html5.lib/HTML5/Serializer/OutputRules.php',  
    './base/html5.lib/HTML5/Serializer/RulesInterface.php',  
    './base/html5.lib/HTML5/Serializer/Traverser.php',  
    './base/html5.lib/HTML5/Elements.php',  
    './base/html5.lib/HTML5/Entities.php',  
    './base/html5.lib/HTML5/Exception.php',  
    './base/html5.lib/HTML5/InstructionProcessor.php'  
);  
  
// find out order for loading class files  
$load_last = array('./base/html5.lib/HTML5.php');  
  
foreach (file($load_last[0]) as $i => $line) {  
  
    // we need 'use HTML5\Some\Part\Foo\Bar\Baz ;'  
    if (substr_count($line, 'use HTML5')) {  
        $line = trim(preg_replace(  
            '~.*use (HTML5[^;]*);.*~',  
            '$1',  
            $line  
        ));  
  
        $line = sprintf(  
            './base/html5.lib/%s.php',  
            str_replace('\\', '/', $line)  
        );  
  
        if (!in_array($line, $load_last)) {  
            $load_last[] = $line;  
        }  
    }  
}  
  
foreach ($files as $f) {  
    if (!in_array($f, $load_last)) {  
        include $f;  
    }  
}  
  
foreach ($load_last as $f) {  
    include $f;  
}

Dieser Code war notwendig, um die PHP-Dateien des HTML5-Parser-Projektes so zu inkludieren, dass keine Fehlermeldungen entstehen und die Klasse vollständig nutzbar ist.

Damit kann ich nun von meinen RegExen auf DOM-Operationen umrüsten. Cool! Man sollte wissen, dass ein DOMDocument eine DOMNode eines fremden DOMDocuments importieren kann. Damit ist es möglich, eine beliebige Node aus einem beliebigen anderen Dokument an beliebiger Stelle wieder einzupflanzen. Ganz wichtig! Hat ne gute Weile gedauert, bis ich das aus der PHP-Dokumentation heraus hatte! Nun kann ich meine HTML-Ausgabe an den Browser dieser DOM-Bibliothek überlassen, oder eben dem HTML5-Parser.

Liebe Grüße,

Felix Riesterer.

--
"Wäre die EU ein Staat, der die Aufnahme in die EU beantragen würde, müsste der Antrag zurückgewiesen werden - aus Mangel an demokratischer Substanz." (Martin Schulz, Präsident des EU-Parlamentes)