2012-05-05 15 views
7

Meine Erfahrung sagt mir, dass one should not use RegExp to parse HTML/XML, und ich stimme voll und ganz zu! Es istWie werden DOM-Parser implementiert?

  • Messy
  • Nicht robust und leicht
  • Reines Übel

Sie alle sagen, "verwenden, um einen DOM-Parser" irgendeine Art gebrochen, die für mich in Ordnung ist. Aber jetzt wurde ich neugierig. Wie funktionieren diese?

Ich suchte nach der Quelle der DOMDocument-Klasse und konnte sie nicht finden. Diese Frage kommt von der Tatsache, dass zum Beispiel filter_var() als eine gute Alternative für die Validierung von E-Mails mit RegExp angesehen wird, aber wenn Sie auf die Quelle schauen, werden Sie sehen, dass RegExp selbst verwendet wird!

Also, wenn Sie einen DOM-Parser in PHP erstellen würden? Wie würdest du das HTML analysieren? Wie haben die das getan?

+2

DOM-Parser werden normalerweise als Tokenizer implementiert. Wenn Sie C# lesen können, kann der Quellcode für das [HTML Agility Pack] (http://htmlagilitypack.codeplex.com) den Ansatz verdeutlichen. – Oded

+4

Über 'filter_var()': Niemand hat je gesagt, dass man eine E-Mail-Adresse nicht mit Regex validieren sollte. Tatsache ist, dass das Schreiben einer Regex für diese Aufgabe, die * richtig * ist, sehr schwierig ist und viel Forschungsaufwand erfordert. Es gibt also Tausende schreckliche Implementierungen. Deshalb sollten Sie einfach 'filter_var()' verwenden. – kapa

+0

Wenn Sie mit XHTML arbeiten, wird ein normaler XML-Parser funktionieren. – Niko

Antwort

5

Ich denke, dass Sie den Artikel How Browsers Work: Behind the Scenes of Modern Web Browsers überprüfen sollten. Es ist eine lange Lektüre, aber es lohnt sich Ihre Zeit. Insbesondere der HTML-Parser-Abschnitt.

Während ich den Artikel nicht gerecht werden kann, wird vielleicht eine flüchtige Zusammenfassung gut sein, einen zu halten, bis sie die Zeit haben, dieses Meisterwerk zu lesen und zu verdauen. Ich muss jedoch zugeben, dass ich in diesem Bereich ein Neuling mit sehr wenig Erfahrung bin. Seit etwa 10 Jahren für das Web professionell entwickelt, ist die Art und Weise, wie der Browser meinen Code handhabt und interpretiert, lange Zeit eine Blackbox.

HTML, XHTML, CSS oder JavaScript - Sie haben die Wahl. Sie haben alle eine Grammatik und ein Vokabular. Englisch ist ein weiteres großartiges Beispiel. Wir haben grammatikalische Regeln, von denen wir erwarten, dass Menschen, Bücher und mehr folgen. Wir haben auch ein Vokabular bestehend aus Substantiven, Verben, Adjektiven und mehr.

Browser interpretieren ein Dokument, indem sie ihre Grammatik sowie ihr Vokabular untersuchen. Wenn es auf Elemente trifft, die es letztendlich nicht versteht, wird es Sie wissen lassen (Ausnahmen auslösen, usw.). Du und ich machen das gleiche gemeinsam - sprich.

Ich liebe Stackoverflow, aber wenn ich geändert könnte eine Sache wäre es absolutamente gebrochen werden wird ...

Hinweis in dem obigen Beispiel, wie Sie sofort beginnen, die Worte und die Beziehungen zwischen den Worten zerpflücken . Der Anfang macht voll und ganz Sinn, "Ich liebe StackOverflow." Dann kommen wir zu "... wenn ich mich ändern könnte", und wir hören sofort auf. "Geändert" gehört nicht hierher. Es ist wahrscheinlich, dass der Autor "Veränderung" meinte.Jetzt ist das Vokabular richtig, aber die Grammatik ist falsch. Etwas später stoßen wir auf "be be", was auch eine grammatikalische Regel verletzen kann, und nur ein bisschen weiter stoßen wir auf das Wort "absoluamente", das nicht zum englischen Wortschatz gehört - ein weiterer Fehler.

Denken Sie an all das in Bezug auf einen DOCTYPE. Ich habe jetzt auf meinem zweiten Monitor die Quelle hinter XHTML 1.0 Strict Doctype geöffnet. Zu seinen Interna gehören Zeilen wie die folgenden:

<!ENTITY % heading "h1|h2|h3|h4|h5|h6"> 

Dies definiert die Überschrift Entitäten. Und solange ich mich an die Grammatik von XHTML halte, kann ich eine davon in meinem Dokument verwenden (<h1>Hello World</h1>). Aber wenn ich versuche, eine bis zu machen, sagen H7, wird der Browser stolpern über das Vokabular als „fremd“ und informieren Sie mich:

„Zeile 7, Spalte 8: Element‚h7‘undefiniert“

Vielleicht beim Parsen des Dokuments finden wir <table. Wir wissen, dass es sich jetzt um ein table Element handelt, das eigene Vokabeln wie tbody, tr usw. hat. Solange wir die Sprache, die Grammatikregeln usw. kennen, wissen wir, wann etwas nicht stimmt. Zurückkommend auf die XHTML 1.0 Strict Doctype, finden wir folgendes:

<!ELEMENT table 
    (caption?, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+))> 
<!ELEMENT caption %Inline;> 
<!ELEMENT thead (tr)+> 
<!ELEMENT tfoot (tr)+> 
<!ELEMENT tbody (tr)+> 
<!ELEMENT colgroup (col)*> 
<!ELEMENT col  EMPTY> 
<!ELEMENT tr  (th|td)+> 
<!ELEMENT th  %Flow;> 
<!ELEMENT td  %Flow;> 

dieser Hinweis gegeben, wir eine laufende Prüfung gegen halten können gleich welcher Herkunft, wir Parsen. Wenn der Autor schreibt tread, anstelle von thead, haben wir einen Standard, mit dem wir feststellen können, dass dies ein Fehler ist. Wenn Probleme nicht gelöst werden und wir keine Regeln finden können, die bestimmten Grammatik- und Wortschatzverwendungen entsprechen, teilen wir dem Autor mit, dass sein Dokument ungültig ist.

Ich mache keineswegs diese Wissenschaftsjustiz, aber ich hoffe, dass dies - wenn nicht mehr - genug ist, dass Sie es in sich selbst finden könnten, um den Artikel zu lesen, auf den als Anfang dieser Antwort verwiesen wird, und vielleicht setzen Sie sich und studieren Sie die verschiedenen DTDs, denen wir Tag für Tag begegnen.

1

Die gute Nachricht ist hier, Sie müssen das Rad nicht neu erfinden. Die libxml library wird in der DOMDocument-Erweiterung von PHP verwendet und der Quellcode ist verfügbar. Have a look there Ich schlage vor.

Und zw., Reguläre Ausdrücke sind nicht immer falsch, aber Sie müssen sie richtig verwenden andere gehen Sie direkt in Hells Küche, werden ein Kitty Serienmörder oder besuchen Chutullu oder wie dieser Typ heißt. Ich schlage daher folgendes vor: REX: XML Shallow Parsing with Regular Expressions.

Aber wenn Sie alles richtig machen, können reguläre Ausdrücke Ihnen beim Parsen sehr helfen. Du solltest nur wissen, was du tust.

+0

Wie ich schon sagte, ich versuche nicht, das Rad neu zu erfinden, ich bin nur neugierig darauf, wie das Rad funktioniert. Auch ich habe versucht, die Quelle für DOMDocument zu finden und konnte es nicht finden. –

+0

Ich habe die Quelle von libxml verlinkt. Siehe auch die Beschreibung der Architektur auf ihrer Website, das Projekt ist ziemlich groß. Und es gibt auch das HTMLPurifier-Projekt, das ein HTML-Parser ist, der in PHP IIRC geschrieben ist. – hakre

Verwandte Themen