3.8. Markierte Bereiche

SGML erlaubt es, dass bestimmte Dokumentabschnitte während der Verarbeitung besonders behandelt werden sollen. Diese Abschnitte werden als markierte Bereiche [8] bezeichnet.

Beispiel 3.14. Aufbau eines markierten Bereiches
<![ SCHLÜSSELWORT [
  Inhalt des markierten Bereiches
]]>

Da es sich bei markierten Bereichen um SGML-Konstrukte handelt, werden sie mit <! eingeleitet. Der eigentliche Anfang des markierten Bereiches wird von der folgenden eckigen Klammer bestimmt. Das darauf folgende SCHLÜSSELWORT legt fest, wie der markierte Inhalt durch einen SGML-Prozessor während der Verarbeitung behandelt werden soll. Der markierte Inhalt selbst beginnt erst nach der zweiten eckigen Klammer und erstreckt sich bis zu den zwei schließenden eckigen Klammern am Ende des Bereiches. Mit Hilfe des > Zeichens wird der mit <! begonnene SGML-Kontext wieder verlassen.

3.8.1. Schlüsselworte für markierte Bereiche

3.8.1.1. CDATA und RCDATA

Die Schlüsselworte CDATA und RCDATA bestimmen das Inhaltsmodell für markierte Bereiche. Dadurch ist es möglich, vom Standardmodell abzuweichen.

Ein SGML-Prozessor muss während der Verarbeitung eines Dokuments zu jedem Zeitpunkt wissen, welches Inhaltsmodell gerade anzuwenden ist.

Was ist ein Inhaltsmodell? Kurz gesagt beschreibt das Inhaltsmodell, welche Art von Inhalt der Parser zu erwarten und wie er damit umzugehen hat.

Bei CDATA und RCDATA handelt es sich wahrscheinlich um die nützlichsten Inhaltsmodelle. CDATA steht für Zeichendaten[9]. Trifft ein Parser auf dieses Inhaltsmodell, wird er annehmen, dass sich im zugehörigen Dokumentenbereich nur gewöhnliche Zeichen befinden. Das bedeutet, dass < und & ihre besondere Bedeutung verlieren und als einfache Zeichen behandelt werden.

RCDATA steht für Entitätenreferenzen und Zeichendaten[10]. Für einen Bereich mit diesem Inhaltsmodell, wird ein Parser davon ausgehen, dass er sowohl Zeichen als auch Enitätenreferenzen finden kann. < verliert hier zwar auch seine besondere Bedeutung, doch & wird weiterhin als Anfang einer Entität interpretiert.

Nützlich ist das CDATA-Modell vor allem dann, wenn es darum geht Texte eins-zu-eins zu übernehmen, in denen < und & gehäuft auftreten. Zwar kann man solche Texte überarbeiten und jedes < durch ein &lt; und jedes & durch ein &amp; ersetzen, doch es wird in den meisten Fällen einfacher sein, für den betreffenden Text CDATA als Inhaltsmodell festzulegen. Ein SGML-Parser wird dann, sobald er auf < oder & trifft, diese als Zeichen in einem Text betrachten.

Anmerkung:

Bei der Verwendung von CDATA und RCDATA als Inhaltsmodell für SGML-Beispiele, wie sie in diesem Dokument enthalten sind, muss bedacht werden, dass der Inhalt eines CDATA-Bereiches nicht validiert wird. dass das SGML in diesen Bereichen gültig ist, muss auf andere Weise sichergestellt werden. Denkbar ist beispielsweise, es in einem separaten Dokument zu erstellen, dort zu prüfen und erst dann in das eigentliche Dokument einzufügen.

Beispiel 3.15. CDATA als Inhaltsmodell für markierte Bereiche
<para>Das ist ein Beispiel, wie man einen Text,
  der viele &lt;- und &amp;-
  Entitäten enthält, in ein Dokument einbinden kann.
  Das Beispiel selbst, das sich innerhalb des markierten Bereiches befindet,
  ist ein HTML-Fragment. Der diesen Text umschließende Tag, beginnend mit
  mit para und endend mit /para, stammt aus der DocBook DTD.</para>

<programlisting>
  <![RCDATA[  
    <p>Dieses Beispiel demonstriert die Verwendung von HTML-Elementen.
      Da spitze Klammern so oft vorkommen, ist es einfacher, das
      gesamte Beispiel als CDATA Abschnitt auszuweisen, als die
      entsprechenden Entitäten zu nutzen.</p>

    <ul>
      <li>Das ist ein Listenelement.</li>
      <li>Das ist ein zweites Listenelement.</li>
      <li>Das ist ein drittes Listenelement.</li>
    </ul>

    <p>Und das hier, das ist das Ende des Beispiels.</p>
  ]]>
</programlisting>

Liest man die Quellen dieser Fibel, wird man feststellen, dass diese Technik durchgängig angewandt wurde.


3.8.1.2. INCLUDE und IGNORE

Das Schlüsselwort INCLUDE legt fest, dass der Inhalt des betreffenden Abschnittes mitverarbeitet wird. Demgegenüber bestimmt IGNORE, dass er ignoriert wird, dass heißt, dass er bei der Verarbeitung übergangen wird und in der Ausgabe nicht enthalten ist.

Beispiel 3.16. Anwendung von INCLUDE und IGNORE in markierten Abschnitten
<![ INCLUDE [
  Dieser Text wird verarbeitet und eingebunden.
]]>

<![ IGNORE [
  Dieser Text wird weder verarbeitet noch eingebunden.
]]>

Für sich alleine ist IGNORE als Anweisung nicht besonders nützlich, da ein Bereich, der von der Verarbeitung ausgenommen sein soll, auch auskommentiert werden kann.

Kombiniert man IGNORE hingegen mit Parameterentitäten, steht so ein Weg zur Verfügung, um dessen Anwendung besser steuern zu können. Zwar können Parameterentitäten nur in einem SGML-Kontext einsetzt werden, da aber markierte Bereiche ebenfalls SGML-Konstrukte sind, ist diese Einschränkung irrelevant.

Soll beispielsweise ein und dasselbe Dokument in zwei unterschiedlichen Varianten produziert werden, einer gedruckten und einer digitalen, und soll nur die digitale zusätzliche Informationen enthalten, kann dies mit einem Trick erreicht werden.

Man definiert eine Parameterentität, der man als Wert die Zeichenkette INCLUDE zuweist und deklariert den betreffenden Bereich, der nur in der digitalen Variante erscheinen soll, als markierten Abschnitt und setzt als Schlüsselwort die zuvor definierte Parameterentität ein.

Soll anstelle der digitalen die gedruckte Variante produziert werden, muss lediglich der Entität IGNORE als Wert zugewiesen und das Ursprungsdokument erneut durch den SGML-Prozessor geschickt werden.

Beispiel 3.17. Kontrolle von markierten Bereichen über Parameterentitäten
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN" [
<!ENTITY % digitale.kopie "INCLUDE">
]]>

...

<![ %digitale.kopie [
  Dieser Satz sollte nur in der digitalen Version enthalten sein.
]]>	  

Bei der Produktion der gedruckten Variante muss der Wert der Entität geändert werden.

<!ENTITY % digitale.kopie "IGNORE">

Bei der Verarbeitung wird als Schlüsselwort in beiden Fällen der von %digitale.kopie repräsentierte Wert verwendet. Im ersten Fall wird der Inhalt des markierten Bereichs mitverarbeitet, im zweiten Fall nicht.


3.8.2. Fingerübung…

  1. Legen Sie eine neue Datei abschnitt.xml an, die folgenden Inhalt hat:

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN" [
    <!ENTITY % text.ausgabe "INCLUDE">
    ]>
    
    <html>
      <head>
        <title>Ein Beispiel mit markierten Abschnitten</title>
      </head>
    
      <body>
        <p>Dieser Absatz <![CDATA[beinhaltet viele <
          Zeichen (< < < < <). Weshalb es einfacher ist,
          ihn als CDATA Bereich auszuweisen. ]]></p>
    
        <![ IGNORE [
        <p>Dieser Absatz wird NICHT in der Ausgabe enthalten sein.</p>
        ]]>
    
        <![ %text.ausgabe [
         <p>Dieser Absatz wird in Abhängigkeit von %text.ausgabe
           mitausgegeben.</p>
        ]]>
      </body>
    </html>
  2. Normalisieren Sie den Inhalt dieser Datei mit Hilfe von osgmlnorm und sehen Sie sich das Ergebnis an. Achten Sie dabei darauf, welche Absätze enthalten beziehungsweise nicht enthalten sind und was aus den CDATA-Bereichen geworden ist.

  3. Ändern Sie die Definition von text.ausgabe so, dass es den Wert IGNORE zugewiesen bekommt. Verarbeiten Sie dann die Datei erneut mit osgmlnorm und vergleichen die Ausgabe mit der vom ersten osgmlnorm Lauf.



[8] auf Englisch marked sections

[9] auf Englisch character data

[10] auf Englisch Entity references and character data

Wenn Sie Fragen zu FreeBSD haben, schicken Sie eine E-Mail an <de-bsd-questions@de.FreeBSD.org>.

Wenn Sie Fragen zu dieser Dokumentation haben, schicken Sie eine E-Mail an <de-bsd-translators@de.FreeBSD.org>.