Christian Kruse: Datei rückwärts einlesen

Beitrag lesen

Hallo Michel,

ich möchte eine HTML-Seite in Ihre Bestandteile zerlegen
und einem Array zuweisen,so ähnlich wie fgetcsv(), um vor
INPUT-Tags einen Text zu formatieren, fehlende Attribute
und Tasg einfügen. Mit fgetss() kann ich nur bestimmte
Tags einlesen.

Eine interessante Aufgabe, aber nicht ganz einfach.
Prinzipiell wuerde ich so vorgehen: Datei komplett einlesen,
den String in 'Tokens' unterteilen und dann eine
hierarchische Struktur erstellen.

Das Tokenizing geht relativ einfach. Pruefe bei jedem
auftreten von <, ob ein Tag anfaengt. Faengt einer an, so
lies ihn bis zuende ein und speichere seine Attribute in
einem assoziativen Array oder so. Ist es ein leeres Element,
fahre weiter im Text. Ist das Element gefuellt (mit Text oder
Elementen ist dabei egal), starte eine neue Rekursionsstufe,
so dass aus einem HTML-Dokument wie diesem:

<html>
 <head>
  <title>text</title>
 </head>
 <body bgcolor="#FFFFFF">
  <h1>text</h1>
  <p>text</p>
 </body>
</html>

folgende Struktur entsteht:

$tree = Array(
  'name'       => 'html',
  'data'       => '',
  'attributes' => Array(),
  'childs'     => Array(
    Array(
      'name'       => 'head',
      'data'       => '',
      'attributes' => Array(),
      'childs'     => Array(
        Array(
          'name'       => 'title',
          'data'       => '',
          'attributes' => Array(),
          'childs'     => Array(
            'name'       => '#text',
            'data'       => 'text',
            'attributes' => Array(),
            'childs'     => Array()
          )
        )
      )
    ),
    Array(
      'name'       => 'body',
      'data'       => '',
      'attributes' => Array(
        'bgcolor' => '#FFFFFF'
      ),
      'childs'     => Array(
        Array(
          'name'       => 'h1',
          'data'       => '',
          'attributes' => Array(),
          'childs'     => Array(
            Array(
              'name'       => '#text',
              'data'       => 'text',
              'attributes' => Array(),
              'childs'     => Array()
            )
          )
        ),
        Array(
          'name'       => 'p',
          'data'       => '',
          'attributes' => Array(),
          'childs'     => Array(
            Array(
              'name'       => '#text',
              'data'       => 'text',
              'attributes' => Array(),
              'childs'     => Array()
            )
          )
        )
      )
    )
  )
);

Hast du diese Struktur korrekt hergestellt, dann kannst du
die Informationen in einem (relativ einfachen) rekursiven
Algorithmus weiterverarbeiten -- optimieren, aufraeumen, etc.

Also einen HTML-Konverter, dabei muss ich aber unabhängig
von doctype erst herausfinden, ob es sich um XHTML oder
HTML handelt.

Oha -- unabhaengig vom Doctype ist so ohne weiteres aber nicht
moeglich. Ist kein Doctype angegeben, wuerde ich von HTML 4.01
oder so ausgehen.

Gruesse,
 CK