Frage

Ich habe eine Reihe von Legacy-Dokumente, die HTML-like sind. Wie in, sie wie HTML aussehen, haben aber zusätzlich aus Tags, die nicht Teil von HTML sind

<strong>This is an example of a <pseud-template>fake tag</pseud-template></strong>

Ich brauche diese Dateien zu analysieren. PHP ist das einzige einzige Werkzeug zur Verfügung. Die Dokumente kommen nicht in der Nähe ist gut XML gebildet.

Mein ursprünglicher Gedanke war, die Methoden auf PHPs loadhtml DOMDocument zu verwenden. Allerdings ersticken diese Methoden auf die Make-up-HTML-Tags, und wird sich weigern, die Zeichenfolge / Datei zu analysieren.

$oDom = new DomDocument();
$oDom->loadHTML("<strong>This is an example of a <pseud-template>fake tag</pseud-template></strong>");
//gives us
DOMDocument::loadHTML() [function.loadHTML]: Tag pseud-template invalid in Entity, line: 1 occured in ....

Die einzige Lösung, ich in der Lage gewesen war, mit zu kommen ist mit String-Ersatzfunktionen, die Dateien zu-Prozess vor, der die ungültigen Tags entfernen wird und ersetzen sie durch einen gültigen HTML-Tag (vielleicht eine Spanne mit einer ID des Tags Name).

Gibt es eine elegantere Lösung? Eine Art und Weise zu lassen DOMDocument wissen über weitere Tags als gültig zu betrachten? Gibt es eine andere, robuste HTML-Parsing-Klasse / Objekt gibt für PHP?

(wenn es nicht offensichtlich ist, halte ich nicht für reguläre Ausdrücke eine gültige Lösung hier)

Aktualisieren : Die Informationen in die falschen Tags Teil des Ziel ist es hier, so etwas wie Tidy ist keine Option. Außerdem bin ich nach etwas, das ein gewisses Maß der Fall ist, wenn nicht alle, Wohlgeformtheits- Bereinigung für mich, weshalb ich war die Methode loadhtml in erster Linie der DomDocument suchen.

War es hilfreich?

Lösung

Sie können unterdrücken Warnungen mit libxml_use_internal_errors , während das Dokument zu laden. Zum Beispiel:.

libxml_use_internal_errors(true);
$doc = new DomDocument();
$doc->loadHTML("<strong>This is an example of a <pseud-template>fake tag</pseud-template></strong>");
libxml_use_internal_errors(false);

Wenn aus irgendeinem Grund, erhalten Sie Zugriff auf die Warnungen müssen, verwenden Sie

Andere Tipps

Ich frage mich, die "schlecht", wenn vorbei HTML durch HTML Tidy könnte helfen als First-Pass? Könnte einen Blick wert sein, wenn Sie das Dokument wohlgeformt bekommen werden, vielleicht könnte man es als reguläre XML-Datei mit DomDocument laden.

@Twan Sie brauchen keine DTD für DOMDocument benutzerdefinierte XML zu analysieren. Verwenden Sie einfach DOMDocument->load(), und solange die XML wohlgeformt ist, kann es zu lesen.

Wenn Sie die Dateien erhalten wohlgeformt werden, das ist, wenn Sie beginnen bei XML-Parser suchen, bevor dass Sie S.O.L. Lok Alejo sagte, Sie unter HTML Tidy , aber es sieht so aus, dass bestimmte ist zu HTML, und ich weiß nicht, wie es mit Ihren benutzerdefinierten Elementen gehen würde.

  

Ich glaube nicht, reguläre Ausdrücke eine gültige Lösung hier

Bis Sie Wohlgeformtheits- haben, das könnte Ihre einzige Option sein. Sobald Sie die Dokumente zu diesem Zeitpunkt erhalten, dann sind Sie in der klaren mit den DOM-Funktionen.

Werfen Sie einen Blick auf die Parser in der PHP-Fit-Port. Der Code ist sauber und wurde ursprünglich für das Laden der schmutzigen HTML von Word gespeichert entworfen. Es ist so konfiguriert Tabellen zu ziehen, kann aber leicht adapated werden.

Sie können die Quelle hier sehen: http://gerd.exit0.net/pat/PHPFIT/ PHPFIT-0.1.0 / Parser.phps

Die Unit-Test zeigt Ihnen, wie es zu benutzen: http://gerd.exit0.net/pat/ PHPFIT / PHPFIT-0.1.0 / test / parser.phps

Meine quick and dirty Lösung für dieses Problem war es, eine Schleife auszuführen, die meine Liste der benutzerdefinierten Tags mit einem regulären Ausdruck übereinstimmt. Die regexp nicht fangen Tags, die eine andere innere benutzerdefinierten Tags in ihnen haben.

Wenn es eine Übereinstimmung gibt, eine Funktion, den Tag zu verarbeiten aufgerufen und gibt die „verarbeitet HTML“. Wenn der benutzerdefinierte Tag in einem anderen benutzerdefinierten Tag als die Eltern war, wird durch die Tatsache, kinderlos, dass die tatsächliche HTML wurde anstelle des Kindes eingeführt, und es wird von der regexp und verarbeitet wird bei der nächsten Iteration der Schleife angepasst werden.

Die Schleife endet, wenn es keine kinderlos benutzerdefinierten Tags sind abgestimmt werden. Insgesamt ist es iteratives (a while-Schleife) und nicht rekursiv.

@Alan Sturm

Ihr Kommentar zu meiner anderen Antwort hat mich zu denken:

  

Wenn Sie eine HTML-Datei mit DOMDocument laden, wird es ein gewisses Maß an Bereinigungs re zu tun: gut Wohlgeformtheits-, erfordert aber alle Tags legit HTML-Tags zu sein. Ich suche nach etwas, das den ehemaligen tut, aber nicht die später. (Alan Sturm)

Führen Sie einen regulären Ausdruck (sorry!) Über die Tags, und wenn es eine findet, die kein gültiges HTML-Element ist, ersetzen Sie es mit einem gültigen Element, das Sie kennen, existiert nicht in einem der Dokumente (blink kommt Geist ...), und geben Sie ihm einen Attributwert mit dem Namen des illegalen Elements, so dass Sie es danach zurück wechseln können. zB:

$code = str_replace("<pseudo-tag>", "<blink rel=\"pseudo-tag\">", $code);
// and then back again...
$code = preg_replace('<blink rel="(.*?)">', '<\1>', $code);

offensichtlich, dass Code wird nicht funktionieren, aber Sie die allgemeine Idee?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top