Składnia języka HTML jest formalnie opisana w języku SGML. Specyfikacja, nazywana w skrócie DTD, precyzuje nie tylko dostępne znaczniki i elementy oraz zasady dotyczące ich zamykania, ale także dopuszczalne atrybuty i poprawne wartości atrybutów, jak również określa dokładnie zawartość każdego elementu HTML.
Języki znacznikowe, m.in. HTML, XHTML i WML, są formalnie opisywane w języku SGML (ang. Standard Generalized Markup Language). Taki szczegółowy opis, określany mianem DTD (ang. Document Type Definition), definiuje wszystkie dostępne znaczniki elementy, atrybuty, dopuszczalne wartości atrybutów oraz precyzuje sposób zagnieżdżania elementów.
Składnia języka HTML jest opisana w dokumencie DTD.
Mówimy, że HTML jest aplikacją języka SGML.
Język HTML jest aplikacją języka SGML.
W skład definicji języka HTML 4.01 wchodzą trzy dialekty: strict, transitional oraz frameset. Różnią się one między sobą kilkoma znacznikami oraz atrybutami. Każdy z dialektów posiada swoją definicję DTD. Dalsza część artykułu będzie poświęcona wyłącznie wersji strict języka HTML.
W opisie DTD języka HTML występują cztery rodzaje zapisów: komentarze, ENTITY, ELEMENT oraz ATTLIST. Zapisy ELEMENT oraz ATTLIST będziemy nazywali deklaracjami, zaś ENTITY - makrodefinicjami.
Rola komentarzy jest oczywista. Ułatwiają one analizę specyfikacji. Komentarze są oznaczane w specyfikacji, podobnie jak w samym HTML, za pomocą napisów <!-- oraz -->.
Komentarze w języku HTML są ograniczone znacznikami <!-- oraz -->. Pomiędzy napisami <! oraz -- nie mogą pojawić się białe znaki. Otwarcie komentarza HTML realizują jedynie cztery następujące po sobie znaki <!--. Natomiast zamknięcie komentarza HTML może zawierać białe znaki pomiędzy napisami -- oraz >. Oto przykłady poprawnych komentarzy w HTML
<!-- komentarz pierwszy --> <!-- komentarz drugi -- >
Należy zatem pamiętać, by nie umieszczać wewnątrz komentarzy HTML dwóch znaków --.
Komentarze wewnątrz DTD, oznaczane podwójnymi minusami, mają postać
-- komentarz --
Dopuszczalne są białe znaki pomiędzy napisami <! oraz >, a podwójnym minusem
<! -- poprawny komentarz DTD -- -- drugi poprawny komentarz DTD -- >
Deklaracja ELEMENT definiuje powinien konkretny element (lub grupę elementów) języka HTML (np. IMG lub H1, H2, ..., H6). Deklaracja ATTLIST definiuje dopuszczalne atrybuty elementu lub elementów. Natomiast deklaracja ENTITY jest makrodefinicją, która skraca całą specyfikację i czynią ją bardziej czytelną.
Formalny opis języka HTML 4.01, składa się wyłącznie z makrodefinicji ENTITY oraz deklaracji ELEMENT i ATTLIST.
Przyjrzyjmy się przykładowi:
<!ENTITY % heading "H1|H2|H3|H4|H5|H6" -- nagłówki -->
Jest to makrodefinicja ustalającą znaczenie napisu %heading;. Rozpoczyna się ona od <!ENTITY %, zaś kończy >. Wewnątrz występuje nazwa makrodefinicji heading, ujęty w cudzysłów napis "H1|H2|H3|H4|H5|H6" będący wartością oraz komentarz -- nagłówki --.
Każde wystąpienie napisu %heading; zostanie zastąpione napisem H1|H2|H3|H4|H5|H6. Wywołanie makrodefinicji ma postać: %heading;. Składa się ono ze znaku procentu, nazwy makrodefinicji oraz opcjonalnego średnika.
Cel wprowadzenia makrodefinicji ENTITY stanie się jasny, przy omawianiu konkretnych znaczników. Najczęściej stosowanymi makrami będą definicje dzielące elementy HTML na dwie grupy: elementy tekstowe - %inline;, oraz elementy blokowe - %block;, jak również trzy główne grupy atrybutów %coreattrs;, %i18n; i %events;. Dodatkowo makrodefinicja %flow; łącząca elementy blokowe i tekstowe, zaś %attrs; zwiera wszystkie atrybuty zdefiniowane w trzech grupach %coreattrs;, %i18n; i %events;. Każda z deklaracji definiująca konkretne elementy będzie się odwoływała przynajmniej do części z powyższych siedmiu makrodefinicji.
Uwaga, makrodefinicje nie mogą występować w HTML a jedynie w DTD. Pewnym rodzajem makr są znaki specjalne (ang. character references), np. < czy . One mogą występować w tekście wewnątrz HTML oraz w wartościach atrybutów.
Dodajmy, że makrodefinicja może wykorzystywać inne, już zdefiniowane makrodefinicje, np.:
<!ENTITY % list "UL | OL"> <!ENTITY % preformatted "PRE"> <!ENTITY % block "P | %heading; | %list; | %preformatted; | DL | DIV | NOSCRIPT | BLOCKQUOTE | FORM | HR | TABLE | FIELDSET | ADDRESS">
W podanym przykładzie definiujemy makro %block;. W opisie wartości stosujemy zdefiniowaną wcześniej makrodefinicję %heading; oraz dwie makrodefinicje podane powyżej: %list; i %preformatted;.
Deklaracja ELEMENT ma postać
<!ELEMENT BR - O EMPTY -- forced line break -->
Określa ona składnię elementu języka HTML. Deklaracja zawiera trzy ważne informacje. Po pierwsze nazwę definiowanego elementu. W przykładzie jest nią BR. Po drugie ustala czy znaczniki otwierający i zamykający są dopuszczalne, wymagane czy opcjonalne. W przykładzie jest to napis - O. Po trzecie określa poprawną zawartość elementu (ang. content model definition). W przykładzie: EMPTY. Napis -- forced line break -- jest oczywiście komentarzem.
Powyższy przykład ustala składnię elementu BR. Napis - O określa, że znacznik otwierający jest wymagany, zaś znacznik zamykający - opcjonalny. Pierwszy znak określa znacznik otwierający, a drugi - znacznik zamykający. W specyfikacji stosowane są dwa znaki: - oraz O. Znak minus oznacza, że znacznik jest wymagany, zaś litera O - że znacznik jest opcjonalny.
Element BR nie posiada żadnej zawartości (napis EMPTY). Jest to tak zwany element pusty. W przypadku elementów pustych znacznik zamykający jest zabroniony.
Rozważmy drugi przykład:
<!ELEMENT (%heading;) - - (%inline;)* -- nagłówek -->
Jest to deklaracja nagłówków H1, ..., H6. Podana wcześniej makrodefinicja %heading; zostanie rozwinięta do "H1|H2|H3|H4|H5|H6". Zatem definiowanymi elementami są H1, ..., H6. Znak | użyty w makrodefinicji jest znakiem alternatywy, zaś nawiasy okrągłe otaczające makro (%heading;) są użyte do grupowania. Innymi słowy deklaracja określa każdy z elementów H1, ..., H6 z osobna (można ją interpretować identycznie jak sześć niezależnych deklaracji postaci <!ELEMENT H1 .... >, <!ELEMENT H2 .... >, itd.)
Jeśli chodzi o znaczniki otwierający i zamykający każdego elementu H1, ..., H6 to są one wymagane. Decyduje o tym napis - -.
Poprawna zawartość natomiast jest określona napisem (%inline;)*. Makrodefinicja %inline; zostanie omówiona w kolejnych punktach, teraz zajmijmy się znaczeniem napisu (...)*. Nawiasy okrągłe grupują elementy, zaś gwiazdka określa, że elementy zawarte w nawiasach mogą wystąpić dowolna liczbę razy. Tabela 1 zawiera zestawienie stosowanych operatorów ustalających liczbę powtórzeń.
Zapis | Znaczenie |
---|---|
Zapis | Znaczenie |
(...) | Grupowanie |
A | może wystąpić dokładnie jeden raz |
A+ | może wystąpić jeden lub więcej razy |
A? | może wystąpić jeden raz lub nie wystąpić wcale |
A* | może wystąpić zero lub więcej razy |
+(A) | może wystąpić |
-(A) | nie może wystąpić |
A | B | musi wystąpić dokładnie jeden element: A lub B (nie oba, nie żaden, a dokładnie jeden z nich) |
A , B | muszą wystąpić oba elementy A i B w dokładnie takiej kolejności |
A & B | muszą wystąpić oba elementy A i B w dowolnej kolejności |
Tabela 1. Składnia opisu zawartości elementów
Zatem napis (%inline;)* mówi, że poprawną zawartością elementów H1, ..., H6 jest dowolna liczba, tj. zero, jeden lub więcej, napisów określonych makrodefinicją %inline;.
Kolejny przykład:
<!ELEMENT UL - - (LI)+ -- unordered list -->
jest deklaracją elementu UL. Znacznik otwierający i zamykający są obowiązkowe (mówią o tym dwa znaki - -), zaś poprawną zawartością jest jeden lub więcej elementów LI (mówi o tym napis (LI)+).
Wreszcie przykład:
<!ELEMENT A - - (%inline;)* -(A) -- anchor -->
pokazuje wykluczanie części elementów z zawartości. Deklaracja ta mówi, że element A posiada dwa wymagane znaczniki, otwierający i zamykający. Poprawna zawartość jest zdefiniowana jako (%inline;)* -(A). Zatem może zawierać dowolna liczbę elementów typu %inline;, natomiast nie może zawierać elementu A (element A jest zawarty w zbiorze elementów %inline;). Jawne wykluczenie ma większą wagę od dołączania.
Ostatni rodzaj deklaracji, ATTLIST, wygląda następująco:
<!ATTLIST BR %coreattrs; -- atrybuty znacznika złamania wiersza -->
Definicja ATTLIST ustala zbiór dopuszczalnych atrybutów elementu.
Deklaracja rozpoczyna się od napisu <!ATTLIST, a kończy >. Wewnątrz, po napisie ATTLIST występuje nazwa elementu BR (zamiast nazwy jednego elementu może pojawić się makrodefinicja). Podany przykład ustala dopuszczalne atrybuty elementu BR. W deklaracji tej, po nazwie elementu występują atrybuty. W przykładzie użyto makrodefinicji %coreattrs;. Napis atrybuty znacznika złamania wiersza pojawia się po dwóch minusach, więc jest komentarzem.
Stwierdzenie, jakie konkretnie atrybuty są dopuszczalne dla elementu BR wymaga sprawdzenia makrodefinicji %coreattrs;.
Jednostka leksykalna SGML | Znaczenie |
---|---|
Jednostka leksykalna SGML | Znaczenie |
ENTITY | Makrodefinicje skracające specyfikację i ułatwiające jej analizę. |
ELEMENT | Deklaracja elementu HTML. Ustalenie konieczności/dopuszczalności/opcjonalności stosowania znaczników otwierającego i zamykającego. Ustalenie poprawnej zawartości elementu. |
ATTLIST | Deklaracja atrybutów elementu HTML. |
Tabela 2. Jednostki leksykalne SGML użyte w DTD
Składnia HTML wyrażona w języku SGML zawiera kilka rodzajów danych. Wartość atrybutu href znacznika <A href="..."> jest innego typu niż na przykład wartość atrybutu class znacznika <H1 class="...">. W celu odróżnienia wartości atrybutów wprowadzono typy danych oraz pewne makrodefinicje.
Dokument DTD stosuje następujące rodzaje danych:
Dane typu CDATA oraz #PCDATA to teksty nie zawierające kodu HTML.
CDATA to tekst stosowany wewnątrz dokumentu DTD, zaś #PCDATA to tekst, jaki występuje w dokumencie HTML.
... <TITLE>"Witaj!"</TITLE> ... <BODY> <H1>Cześć!</H1> <P class="wprowadzenie"> ... treść strony ... Zajrzyj <A href="adres.html">tutaj</A>. ... </P> </BODY>
W przedstawionym przykładzie danymi typu #PCDATA są napisy:
Jedynymi elementami, które mogą zawierać dane #PCDATA są: elementy tekstowe (patrz tabele 4 i 6), TITLE, OPTION, TEXTAREA oraz FIELDSET.
Opisy wartości atrybutów oraz zawartości elementów będą stosowały dane typu CDATA, ID, NAME, NUMBER, IDREF oraz IDREFS.
Na bazie typu CDATA określone są makrodefinicje %StyleSheet; oraz %URI;:
<!ENTITY % StyleSheet "CDATA" -- style sheet data --> <!ENTITY % URI "CDATA" -- a Uniform Resource Identifier, see [URI] -->
Zarówno %StyleSheet; jak i %URI; zostaną rozwinięte do CDATA.
Specyfikacja języka HTML nie nakłada żadnych ograniczeń na to, czym jest poprawny styl lub adres URI. Jedyne, co jest powiedziane w specyfikacji to to, że są to teksty nie zawierające kodu HTML. W razie potrzeby dozwolone jest użycie znaków specjalnych. (W istocie, w przypadku skryptów i stylów sprawa jest nieco bardziej skomplikowana. Otóż skrypt i styl mogą zawierać znaczniki i znaki specjalne, a mimo to nie podlegają interpretacji. Zostają przekazane w niezmienionej postaci do odpowiedniego modułu odpowiedzialnego za interpretacje skryptu bądź stylu. Pierwsze wystąpienie sekwencji znaków </ stanowi znak końca skryptu lub stylu.)
W identyczny sposób zdefiniowano makrodefinicje: %ContentType;, %ContentTypes;, %Charset;, %Charsets;, %LinkTypes;, %MediaDesc;, %Datetime;, %Script; oraz %Text.
Zapamiętajmy zatem, że powyższe makra, w pewnym uproszczeniu, stanowią po prostu tekst nie zawierający kodu HTML.
W specyfikacji, niemal na każdym kroku występują cztery grupy atrybutów %coreattrs;, %i18n;, %events; oraz %attrs;. Przyjrzyjmy się makrodefinicjom, które definiują podane grupy.
Makrodefinicja %coreattrs; jest następująca:
<!ENTITY % coreattrs "id ID #IMPLIED -- document-wide unique id -- class CDATA #IMPLIED -- space-separated list of classes -- style %StyleSheet; #IMPLIED -- associated style info -- title %Text; #IMPLIED -- advisory title --" >
Wynika z niej, że %coreattrs; to następujące atrybuty:
Teksty ograniczone znakami -- to oczywiście komentarze, zaś napis #IMPLIED oznacza, że jeżeli zadany atrybut nie został określony wewnątrz dokumentu HTML, to ustaleniem jego wartości zajmuje się przeglądarka WWW. Innymi napisami, które mogą się pojawić w miejscu #IMPLIED są:
Cała wartość makra %coreattrs; jest ograniczona znakami ". Wymaga tego składnia makrodefinicji ENTITY.
Jak widać w skład grupy coreattrs wchodzą atrybuty id, class, style oraz title ustalające identyfikator, klasę, styl oraz tytuł elementu.
Druga ważna grupa atrybutów to atrybuty %i18n;:
<!ENTITY % i18n "lang %LanguageCode; #IMPLIED -- language code -- dir (ltr|rtl) #IMPLIED -- direction for weak/neutral text --" >
Wartość atrybutu lang jest określona poprzez makro %LanguageCode;, zaś atrybut dir może przyjmować jedną z dwóch wartości: ltr lub rtl.
Atrybuty te służą do określenia języka danego elementu oraz kierunku przetwarzania tekstu: od lewej do prawej (ltr) lub od prawej do lewej (rtl).
Wreszcie atrybuty %events;:
<!ENTITY % events "onclick %Script; #IMPLIED -- a pointer button was clicked -- ondblclick %Script; #IMPLIED -- a pointer button was double clicked-- onmousedown %Script; #IMPLIED -- a pointer button was pressed down -- onmouseup %Script; #IMPLIED -- a pointer button was released -- onmouseover %Script; #IMPLIED -- a pointer was moved onto -- onmousemove %Script; #IMPLIED -- a pointer was moved within -- onmouseout %Script; #IMPLIED -- a pointer was moved away -- onkeypress %Script; #IMPLIED -- a key was pressed and released -- onkeydown %Script; #IMPLIED -- a key was pressed down -- onkeyup %Script; #IMPLIED -- a key was released --" >
definiują procedury obsługi zdarzeń. Ich poprawna wartość jest zdefiniowana makrem %Script;.
Makro %attrs; stanowi jedynie skrót, który uwzględnia wszystkie atrybuty występujące w grupach %coreattrs;, %i18n; oraz %events;:
<!ENTITY % attrs "%coreattrs; %i18n; %events;">
Makrodefinicja | Atrybuty |
---|---|
Makrodefinicja | Atrybuty |
%coreattrs; | id, class, style, title |
%i18n; | lang, |
%events; | onclick, ondblclick, onmousedown, onmouseup, onmouseover, onmousemove, onmouseout, onkeypress, onkeydown, onkeyup |
%attrs; | wszystkie powyższe |
Tabela 3. Trzy główne grupy atrybutów i ich makrodefinicje
Specyfikacja HTML dzieli wszystkie dostępne elementy języka na dwie główne grupy: elementy tekstowe (ang. inline elements) oraz elementy blokowe (ang. block elements). Przykładami elementów tekstowych są STRONG oraz EM, zaś blokowych - P, DIV czy TABLE. W pewnym uproszczeniu można powiedzieć, że zawartość elementów tekstowych jest ograniczona do napisów ewentualnie wzbogaconych o inne elementy tekstowe, zaś elementy blokowe to duże kontenery, które mogą zawierać zarówno inne elementy blokowe jak i tekstowe.
Szczegółowa definicja zbioru elementów tekstowych i blokowych jest kilku etapowa.
Najpierw zdefiniowane są makra ustalające cztery grupy elementów HTML: style czcionek (%fontstyle;), elementy frazowe (%phrase;), elementy specjalne (%special;) oraz kontrolki formularzy (%formctrl;):
<!ENTITY % fontstyle "TT | I | B | BIG | SMALL"> <!ENTITY % phrase "EM | STRONG | DFN | CODE | SAMP | KBD | VAR | CITE | ABBR | ACRONYM"> <!ENTITY % special "A | IMG | OBJECT | BR | SCRIPT | MAP | Q | SUB | SUP | SPAN | BDO"> <!ENTITY % formctrl "INPUT | SELECT | TEXTAREA | LABEL | BUTTON">
Wykorzystując powyższe cztery makrodefinicje, elementy tekstowe są zdefiniowane jako:
<!ENTITY % inline "#PCDATA | %fontstyle; | %phrase; | %special; | %formctrl;">
Uwaga, wprawdzie elementy z grupy %fontstyle;, czyli TT, I, B, BIG oraz SMALL, nie są zabronione w języku HTML 4.01 strict, jednak specyfikacja wyraźnie odradza ich stosowanie.
Makrodefinicja | Elementy | Uwagi |
---|---|---|
Makrodefinicja | Elementy | Uwagi |
#PCDATA | tekst nie zawierający kodu HTML | dozwolone są znaki specjalne |
%fontstyle; | TT, I, B, BIG, SMALL | elementy niezalecane |
%phrase; | EM, STRONG, DFN, CODE, SAMP, KBD, VAR, CITE, ABBR, ACRONYM | - |
%special; | A, IMG, OBJECT, BR, SCRIPT, MAP, Q, SUB, SUP, SPAN, BDO | - |
%formctrl; | INPUT, SELECT, TEXTAREA, LABEL, BUTTON | - |
Tabela 4. Elementy tekstowe języka HTML
Definicja elementów blokowych rozpoczyna się od określenia makr:
<!ENTITY % heading "H1|H2|H3|H4|H5|H6"> <!ENTITY % list "UL | OL"> <!ENTITY % preformatted "PRE">
Do grupy elementów blokowy należą elementy wymienione w następującej makrodefinicji:
<!ENTITY % block "P | %heading; | %list; | %preformatted; | DL | DIV | NOSCRIPT | BLOCKQUOTE | FORM | HR | TABLE | FIELDSET | ADDRESS">
Makrodefinicja | Elementy |
---|---|
Makrodefinicja | Elementy |
%heading; | H1, H2, H3, H4, H5, H6 |
%list; | UL, OL |
%preformatted; | PRE |
- | P, DL, DIV, NOSCRIPT, BLOCKQUOTE, FORM, HR, TABLE, FIELDSET, ADDRESS |
Tabela 5. Elementy blokowe języka HTML
Dodatkowa makrodefinicja %flow;:
<!ENTITY % flow "%block; | %inline;">
będzie przydatna wówczas, gdy dopuszczalną wartością elementu będą zarówno elementy blokowe jak i tekstowe.
Tekstowe | Blokowe |
---|---|
Tekstowe | Blokowe |
EM, STRONG, DFN, CODE, SAMP, KBD, VAR, CITE, ABBR, ACRONYM, A, IMG, OBJECT, BR, SCRIPT, MAP, Q, SUB, SUP, SPAN, BDO, INPUT, SELECT, TEXTAREA, LABEL, BUTTON | H1, H2, H3, H4, H5, H6, UL, OL, PRE, P, DL, DIV, NOSCRIPT, BLOCKQUOTE, FORM, HR, TABLE, FIELDSET, ADDRESS |
Tabela 6. Dwie główne grupy elementów HTML
Po wstępnym omówieniu zawartości dokumentu DTD przyjrzyjmy się konkretnym znacznikom. Rozpocznijmy od elementów definiujących strukturę dokumentu: HTML, HEAD, BODY, TITLE.
Element HTML jest zdefiniowany następująco:
<!ENTITY % html.content "HEAD, BODY"> <!ELEMENT HTML O O (%html.content;) -- document root element --> <!ATTLIST HTML %i18n; -- lang, dir -- >
Jak widać element HTML ma oba znaczniki opcjonalne (dwie litery O O). Jego zawartość stanowią zawsze dwa elementy: pierwszym jest HEAD, drugim - BODY (patrz zapis A , B w tabeli 1). Zauważmy, że element HTML zawiera elementy HEAD i BODY nawet wówczas, gdy dokument jest pozbawiony znaczników otwierających lub zamykających elementy HTML, HEAD oraz BODY. Jedynymi atrybutami, jakie można nadać elementowi HTML są atrybuty grupy %i18n; ustalające język i kierunek przetwarzania tekstu.
Znacznik otwierający: opcjonalny.
Znacznik zamykający: opcjonalny.
Zawartość: muszą wystąpić elementy HEAD oraz BODY (w dokładnie takiej kolejności).
Nie może wystąpić wewnątrz żadnego elementu.
Atrybuty: %i18n;.
Oto definicja elementu BODY:
<!ELEMENT BODY O O (%block;|SCRIPT)+ +(INS|DEL) -- document body --> <!ATTLIST BODY %attrs; -- %coreattrs, %i18n, %events -- onload %Script; #IMPLIED -- the document has been loaded -- onunload %Script; #IMPLIED -- the document has been removed -- >
Wynika z niej, że element body posiada wszystkie atrybuty grup %coreattrs;, %i18n; oraz %events;. Dodatkowo element ten posiada dwa atrybuty ustalające obsługę zdarzeń onload oraz onunload. Poprawną zawartością elementu BODY jest jakikolwiek element blokowy lub element SCRIPT (element blokowy lub element SCRIPT musi wystąpić co najmniej raz). Zawartość może dodatkowo zawierać elementy INS oraz DEL. Z definicji tej wynika między innymi fakt, że bezpośrednio w treści dokumentu nie możemy umieszczać tekstu. Kod
PRZYKŁAD NIEPOPRAWNY <BODY> Witaj na mojej stronie! </BODY>
jest niepoprawny.
Znacznik otwierający: opcjonalny.
Znacznik zamykający: opcjonalny.
Zawartość: dowolny element blokowy lub element SCRIPT co najmniej jeden raz. Dodatkowo mogą wystąpić elementy INS oraz DEL.
Występuje zawsze dokładnie raz (nawet jeśli strona nie zawiera znaczników <BODY> oraz </BODY>) wewnątrz elementu HTML po elemencie HEAD.
Atrybuty: %attrs;, onload, onunload.
Nagłówek strony, stanowiący zawartość elementu HEAD, jest zdefiniowany następująco:
<!ENTITY % head.misc "SCRIPT|STYLE|META|LINK|OBJECT" -- repeatable head elements --> <!ENTITY % head.content "TITLE & BASE?"> <!ELEMENT HEAD O O (%head.content;) +(%head.misc;) -- document head --> <!ATTLIST HEAD %i18n; -- lang, dir -- profile %URI; #IMPLIED -- named dictionary of meta info -- >
Z definicji tej wynika, że zarówno znacznik otwierający jak i zamykający elementu HEAD są opcjonalne. Atrybutami, jakie możemy określić w odniesieniu do HEAD są atrybuty grupy %i18n; oraz profile. Poprawna zawartość jest opisana w sposób dość zawiły.
Makro head.content ma wartość "TITLE & BASE?". Znak zapytania mówi, że BASE występuje jeden raz lub nie występuje wcale. Natomiast znak & definiuje, że zarówno TITLE jak i BASE? muszą wystąpić dokładnie po razie w dowolnej kolejności. Łącząc oba warunki otrzymamy, że poprawną zawartością jest albo sam element TITLE, albo TITLE i BASE występujące w dowolnej kolejności.
Po rozszyfrowaniu makra wróćmy do poprawnej zawartości elementu HEAD. Zawartość jest zdefiniowana jako (%head.content;) +(%head.misc;). A zatem, tak jak powiedzieliśmy element TITLE musi się pojawić; ewentualnie może mu towarzyszyć element BASE. Dodatkowo może się pojawić dowolną liczbę razy każdy z elementów SCRIPT, STYLE, META, LINK oraz OBJECT.
Znacznik otwierający: opcjonalny.
Znacznik zamykający: opcjonalny.
Zawartość: musi pojawić się dokładnie jeden element TITLE, ewentualnie może pojawić się dokładnie jeden element BASE. Dodatkowo może zawierać dowolną liczbę elementów SCRIPT, STYLE, META, LINK oraz OBJECT (w dowolnej kolejności).
Występuje zawsze dokładnie jeden raz wewnątrz elementu HTML przed elementem BODY.
Atrybuty: %i18n;, profile.
Deklaracja elementu TITLE:
<!ELEMENT TITLE - - (#PCDATA) -(%head.misc;) -- document title --> <!ATTLIST TITLE %i18n>
mówi, że dopuszczalną wartością jest jedynie tekst nie zawierający kodu HTML. Element TITLE posiada jedynie atrybuty grupy %i18n;.
Znacznik otwierający: wymagany.
Znacznik zamykający: wymagany.
Zawartość: może zawierać jedynie tekst, bez kodu HTML.
Musi wystąpić dokładnie raz wewnątrz elementu HEAD. Może być poprzedzony jedynie przez element BASE.
Atrybuty: %i18n;.
Element BASE jest pusty, i posiada jeden wymagany atrybut href, który jest adresem URI:
<!ELEMENT BASE - O EMPTY -- document base URI --> <!ATTLIST BASE href %URI; #REQUIRED -- URI that acts as base URI -- >
Znacznik otwierający: wymagany.
Znacznik zamykający: zabroniony.
Zawartość: element pusty.
Może wystąpić dokładnie jeden wewnątrz elementu HEAD.
Atrybuty: wymagany href.
Drugim pustym elementem nagłówka jest element META:
<!ELEMENT META - O EMPTY -- generic metainformation --> <!ATTLIST META %i18n; -- lang, dir, for use with content -- http-equiv NAME #IMPLIED -- HTTP response header name -- name NAME #IMPLIED -- metainformation name -- content CDATA #REQUIRED -- associated information -- scheme CDATA #IMPLIED -- select form of content -- >
Atrybutami elementu META są atrybuty grupy %i18n; oraz http-equiv, name, content i scheme, przy czym atrybut content jest zawsze wymagany.
Znacznik otwierający: wymagany.
Znacznik zamykający: zabroniony.
Zawartość: element pusty.
Może wystąpić dowolną liczbę razy w nagłówku (tj. wewnątrz elementu HEAD).
Atrybuty: wymagany content, %i18n;, http-equiv, name, scheme.
Ostatnimi dwoma elementami nagłówka są STYLE oraz SCRIPT, których definicje przedstawia listing 1.
<!ELEMENT STYLE - - %StyleSheet -- style info --> <!ATTLIST STYLE %i18n; -- lang, dir, for use with title -- type %ContentType; #REQUIRED -- content type of style language -- media %MediaDesc; #IMPLIED -- designed for use with these media -- title %Text; #IMPLIED -- advisory title -- > <!ELEMENT SCRIPT - - %Script; -- script statements --> <!ATTLIST SCRIPT charset %Charset; #IMPLIED -- char encoding of linked resource -- type %ContentType; #REQUIRED -- content type of script language -- src %URI; #IMPLIED -- URI for an external script -- defer (defer) #IMPLIED -- UA may defer execution of script -- event CDATA #IMPLIED -- reserved for possible future use -- for %URI; #IMPLIED -- reserved for possible future use -- >
Listing 1. DTD elementów STYLE oraz SCRIPT.
Oba te elementy posiadają obowiązkowy atrybut type. Znaczniki otwierający i zamykający są obowiązkowe zarówno w przypadku elementu SCRIPT jak i STYLE. Natomiast zawartością każdego z nich może być tekst nie zawierający kodu HTML (wartością makr %StyleSheet; i %Script; jest CDATA).
Znacznik otwierający: wymagany.
Znacznik zamykający: wymagany.
Zawartość: tekst CDATA nie zawierający kodu HTML. Faktycznym znakiem końca elementu STYLE jest znacznik </STYLE>. Cała zawartość elementu STYLE jest przekazywana do modułu interpretacji styli bez jakiejkolwiek interpretacji ze strony parsera HTML.
Może wystąpić dowolną liczbę razy w nagłówku (tj. wewnątrz elementu HEAD).
Atrybuty: wymagany type, %i18n;, media, title.
Znacznik otwierający: wymagany.
Znacznik zamykający: wymagany.
Zawartość: tekst CDATA nie zawierający kodu HTML. Faktycznym znakiem końca elementu SCRIPT jest znacznik </SCRIPT>. Cała zawartość elementu SCRIPT jest przekazywana do modułu wykonującego skrypt bez jakiejkolwiek interpretacji ze strony parsera HTML.
Może wystąpić dowolną liczbę razy w nagłówku (tj. wewnątrz elementu HEAD).
Atrybuty: wymagany type, charset, src, defer, event, for.
Jak się okazuje, język HTML nie jest wcale taki banalny jak to wygląda na pierwszy rzut oka. Już reguły składniowe dotyczące pierwszych elementów HTML, HEAD, BODY, TITLE, BASE, META, LINK, OBJECT SCRIPT i STYLE są na tyle zawiłe, że warto się zastanowić, w jaki sposób nad nimi zapanować.
Z pomocą przychodzą nam programy, które wykrywają błędy języka HTML. Programy takie nazywane są w żargonie walidatorami; obszerny przegląd walidatorów został opublikowany na łamach MI 10/2003.
Organizacja W3C, zajmująca się standaryzacją WWW, prowadzi serwis walidacyjny pod adresem http://validator.w3.org. Skorzystanie z tego serwisu wymaga umieszczenia badanej witryny na dowolnym serwerze (tak by strona posiadała adres URL).
Dokument walidacja.html zawiera wyniki analizy kilku wariantów jednej strony WWW. Strona ta zawiera wyłącznie elementy HTML, HEAD, BODY, TITLE, META (kodowanie polskich znaków), H1 oraz znacznik DOCTYPE. Kolejno usuwane są różne elementy, zmieniana ich kolejność i analizowane informacje zwrócone przez walidator. Na tej podstawie ustalony zostaje szablon pustego dokumentu WWW.
Czy tak dokładna znajomość języka HTML jest konieczna? Czy jest przydatna?
Cóż, odpowiedzi na te pytania każdy musi szukać sam. Moim zdaniem tworzenie poprawnych dokumentów HTML od początku pracy nad serwisem i nadawanie im odpowiedniej struktury w ramach rozwoju aplikacji ma praktyczne korzyści. Jakie? Jeśli kod HTML jest poprawny i posiada odpowiednią strukturę, to wprowadzanie poprawek i ulepszeń będzie stosunkowo proste, a przynajmniej wykonalne. Przeglądając różne kody HTML, niejednokrotnie dochodzę do wniosku, że szybciej przygotuję nowe rozwiązanie, niż przeanalizuję i poprawię stare.
Zwróćmy uwagę, że kontrola poprawności kodu HTML jest automatyczna i nie wymaga godzin ślęczenia w celu odnalezienia błędu. A zatem niewielkim kosztem, tj. sprawdzając poprawność kodu w miarę tworzenia serwisu WWW, a nie po fakcie, możemy nie tylko przygotować poprawne strony WWW, ale także nabrać nawyków, które zaowocują w przyszłości.