Ji°φ Kosek ml.
V ·vodnφm Φlßnku o XML jsme si °ekli, ₧e XML-dokument m∙₧e vyhovovat urΦitΘmu typu dokumentu. Definice typu dokumentu (DTD) p°itom °φkß, kterΘ elementy a atributy m∙₧eme v dokumentu pou₧φt. Navφc je zde definovßno, v jak²ch vzßjemn²ch vztazφch mohou b²t jednotlivΘ elementy pou₧ity. DTD je tedy u₧iteΦn² nßstroj, kter² nßm umo₧nφ hlφdat, zda majφ naÜe dokumenty sprßvnou strukturu. Ve sv∞t∞ se pou₧φvß mnoho DTD, kterΘ vyhovujφ r∙zn²m po₧adavk∙m. Mezi jedno z nejznßm∞jÜφch pat°φ nap°φklad DocBook, kterΘ definuje elementy a atributy vhodnΘ pro znaΦkovßnφ technickΘ dokumentace.
Tφm, ₧e naÜe dokumenty zalo₧φme na urΦitΘmu DTD, zφskßme hned dv∞ v²hody. Jednak m∙₧eme pomocφ parseru kontrolovat, zda mß nßÜ dokument sprßvnou strukturu. Druhß v²hoda je patrnß p°i pou₧itφ standardnφch DTD jako HTML nebo DocBook -- k dispozici budeme mφt mnoho u₧iteΦn²ch a jedno·Φelov²ch nßstroj∙ navrhnut²ch pro konkrΘtnφ DTD. Nap°φklad nenφ problΘm pro DocBook sehnat definici styl∙ vhodn²ch pro formßtovßnφ dokumentace Φi programy, kterΘ umφ dokumenty DocBook konvertovat do HTML a dalÜφch formßt∙.
DTD se k dokumentu p°idßvß pomocφ deklarace typu dokumentu (DOCTYPE), kterß je umφst∞na na zaΦßtku dokumentu ihned za XML deklaracφ. NejΦast∞ji je DTD ulo₧eno v samostatnΘm souboru, aby mohlo b²t vyu₧φvßno v mnoha dokumentech. V tomto p°φpad∞ mß deklarace tvar:
<!DOCTYPE ko°enov²_element SYSTEM "URL">
URL p°itom udßvß adresu nebo jmΘno souboru, ve kterΘm je ulo₧eno DTD. Ko°enov² element je jmΘno elementu, kter² je v DTD definovan² jako ko°enov² -- tj. obsahuje vÜechny dalÜφ elementy dokumentu.
Pro n∞kterß b∞₧n∞ pou₧φvanß a standardizovanß DTD je zbyteΦnΘ, aby
si parser a dalÜφ aplikace Φetly DTD v₧dy ze sφt∞. Mnohem logiΦt∞jÜφ
by bylo, aby v systΘmu byla p°φtomna lokßlnφ kopie soubor∙
s DTD. To je v XML mo₧nΘ pomocφ takzvan²ch ve°ejn²ch identifikßtor∙. K oznaΦenφ DTD
pou₧ijeme n∞jak² textov² °et∞zec. XML-aplikace pak ve svΘm
konfiguraΦnφm souboru zjistφ, ve kterΘm souboru je ulo₧eno p°φsluÜnΘ
DTD. Mφsto slova SYSTEM
nynφ pou₧ijeme v²raz
PUBLIC
, ze kter²m uvedeme identifikßtor DTD. Nakonec vÜak
stejn∞ musφme p°ipojit URL, kterΘ ukazuje na soubor s DTD, aby
mohla aplikace DTD zφskat i v p°φpad∞, ₧e nerozpoznß ve°ejn²
identifikßtor. Deklarace typu dokumentu pak m∙₧e dopadnout t°eba
takto:
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V3.1//EN" "docbook.dtd">
DTD m∙₧eme umφstit i p°φmo do dokumentu pomocφ nßsledujφcφho zßpisu.
<!DOCTYPE kniha [ ... DTD ... ]>
Umφst∞nφ DTD p°φmo do dokumentu nenφ p°φliÜ ΦastΘ, proto₧e pak ztrßcφme mo₧nost sdφlenφ jednoho DTD mezi n∞kolika dokumenty. U₧iteΦn∞jÜφ je vÜak mo₧nost zkombinovat ob∞ p°edeÜlΘ metody a externφ DTD upravit pomocφ lokßln∞ uveden²ch definic. Lokßlnφ Φßst DTD se zpracovßvß jeÜt∞ p°ed tou externφ a m∙₧e tedy zm∞nit n∞kterΘ definice ulo₧enΘ v externφm DTD.
<!DOCTYPE kniha SYSTEM "kniha.dtd" [ ... definice, kterΘ zm∞nφ nebo rozÜφ°φ kniha.dtd ... ]>
Kdy₧ vφme, jak p°ipojit DTD k dokumentu, m∙₧eme se podφvat na to, jak samotnΘ DTD vypadß. DTD obsahuje deklarace Φty° typ∙:
Deklarace novΘho elementu je velice jednoduchß. Mß nßsledujφcφ tvar:
<!ELEMENT nßzev_elementu obsah_elementu>
Nßzev elementu musφ zaΦφnat pφsmenem. DalÜφ znaky nßzvu mohou
obsahovat pφsmena, Φφslice a n∞kterΘ specißlnφ znaky jako
'.
', '-
', '_
' a
':
'. DΘlka jmΘna nenφ nikterak omezenß. Narozdφl od HTML
je d∙le₧itß velikost pφsmen. Nßsledujφcφ dva °ßdky deklarujφ dva r∙znΘ
elementy kapitola
a Kapitola
.
<!ELEMENT kapitola ...> <!ELEMENT Kapitola ...>
Nejzajφmav∞jÜφ je vÜak poslednφ Φßst deklarace elementu, kterß
definuje, co m∙₧e element obsahovat. NejjednoduÜÜφ je prßzdn² element,
kter² nem∙₧e obsahovat ₧ßdnΘ dalÜφ elementy nebo text. P°φkladem
takovΘho elementu mohou b²t nap°φklad elementy br
a
hr
, kterΘ d∙v∞rn∞ znßme z HTML. Jejich deklarace by
vypadala nßsledovn∞:
<!ELEMENT br EMPTY> <!ELEMENT hr EMPTY>
Prßv∞ klφΦovΘ slovo EMPTY
urΦuje, ₧e element nesmφ nic
obsahovat. V dokumentu pak musφme psßt bu∩
<br></br>
, nebo zkrßcen∞
<br/>
. Nenφ vÜak mo₧n² zßpis
<br>
, proto₧e by parser zcela marn∞ hledal
ukonΦovacφ tag </br>
.
Krom∞ v²Üe zmφn∞n²ch p°φpad∙ se prßzdnΘ elementy pou₧φvajφ nap°φklad pro vklßdßnφ obrßzk∙. Pomocφ atribut∙ elementu pak urΦφme soubor, ve kterΘm je obrßzek ulo₧en.
Protip≤lem k EMPTY
je ANY
. Toto klφΦovΘ
slovo nßm zajistφ, ₧e element m∙₧e obsahovat libovolnΘ dalÜφ elementy
a text. ANY
se v praxi moc Φasto nevyu₧φvß, proto₧e pro
pot°eby v∞tÜiny aplikacφ p°φliÜ uvol≥uje strukturu dokumentu. Vyu₧itφ
nalezne nap°φklad p°i nßvrhu a lad∞nφ DTD, kdy nechceme najednou
napsat celΘ DTD.
<!ELEMENT cokoliv ANY>
V∞tÜinou mßme na vno°enΘ elementy mnohem striktn∞jÜφ po₧adavky a s
EMPTY
a ANY
nevystaΦφme. V tomto p°φpad∞ pak
pou₧ijeme tzv. modelovou skupinu (model group). Modelovß
skupina se pou₧φvß pro definici element∙, kterΘ obsahujφ dalÜφ
elementy nebo majφ smφÜen² obsah (obsahujφ ji₧ p°φmo text a
elementy).
Modelovß skupina je v₧dy uzav°ena do kulat²ch zßvorek a obsahuje
alespo≥ jedno slovo. Tφmto slovem nejΦast∞ji b²vß jmΘno elementu,
kter² m∙₧e b²t obsa₧en v prßv∞ definovanΘm elementu. Vno°enΘ
elementy m∙₧eme navzßjem kombinovat pomocφ odd∞lovaΦ∙ ',
'
a '|
'. Elementy odd∞lenΘ Φßrkou musφ nßsledovat
v po°adφ, v jakΘm jsou uvedeny. Pokud mß tedy element
html
obsahovat zßhlavφ (head
) a t∞lo
(body
), pou₧ijeme deklaraci:
<!ELEMENT html (head, body)>
Pokud naopak elementy odd∞lφme znakem '|
' m∙₧e b²t
obsa₧en pouze jeden z nich. P°φklad: potomek m∙₧e b²t dcera nebo
syn. V DTD to vyjßd°φme takto:
<!ELEMENT potomek (dcera | syn)>
Pomocφ zßvorek m∙₧eme ob∞ dv∞ varianty navzßjem kombinovat. Pokud
mß n∞jak² element obsahovat elementy a
, b
a
za nimi bu∩ c
nebo d
, pou₧ijeme modelovou
skupinu (a, b, (c | d))
.
Krom∞ po°adφ element∙ musφme urΦit jejich poΦet, zda jsou povinnΘ
Φi zda se mohou opakovat. Pokud v modelovΘ skupin∞ uvedeme pouze jmΘno
elementu, musφ b²t element p°φtomen prßv∞ jednou. Pokud je vÜak v²skyt
elementu nepovinn², uvedeme za jeho jmΘno znak '?
'. Pokud
nap°φklad Φlßnek obsahuje v₧dy nßzev, ale autora obsahovat nemusφ,
m∙₧eme pou₧φt nßsledujφcφ deklaraci:
<!ELEMENT clanek (nazev, autor?)>
DalÜφ obvyklou situacφ je, ₧e n∞jak² element se m∙₧e opakovat, ale musφ b²t p°φtomen alespo≥ jednou. Nap°φklad kniha se sklßdß z n∞kolika kapitol, ale musφ obsahovat alespo≥ jednu kapitolu:
<!ELEMENT kniha (kapitola+)>
Vra¥me se k p°edchozφmu p°φkladu a p°edklßdejme, ₧e Φlßnek m∙₧e mφt
vφce autor∙ a nemusφ mφt autora ₧ßdnΘho. V tomto p°φpad∞ s v²hodou
vyu₧ijeme znak '*
', kter² indikuje libovoln² poΦet
opakovßnφ.
<!ELEMENT clanek (nazev, autor*)>
VÜe m∙₧eme podle pot°eby kombinovat. Pokud chceme vyjßd°it, ₧e
seznam obsahuje alespo≥ dv∞ polo₧ky, m∙₧eme pou₧φt modelovou skupinu
(polozka, polozka+)
.
Indikßtor poΦtu v²skyt∙ m∙₧eme p°ipojit i za modelovou
skupinu. Nap°φklad zßpis (a, b)?
°φkß, ₧e se elementy
a
a b
bu∩ musφ vyskytovat v danΘm po°adφ,
nebo nesmφ b²t pou₧ity.
Specißlnφ pozornost si zaslou₧φ p°φpad, kdy je obsahem elementu ji₧
samotn² text. To vyjßd°φme pomocφ slova #PCDATA
. Pokud by
nap°φklad element em
obsahoval ji₧ pouze text, a ne dalÜφ
elementy, pou₧ili bychom pro jeho deklaraci zßpis:
<!ELEMENT em (#PCDATA)>
Pokud m∙₧e element obsahovat jak text tak elementy °φkßme, ₧e mß
smφÜen² obsah. V tomto p°φpad∞ musφ mφt deklarace jeho obsahu
specißlnφ tvar. #PCDATA
musφ b²t uvedeno ve skupin∞ jako
prvnφ, skupina musφ b²t spojena pomocφ operßtoru '|
' a
musφ b²t voliteln∞ opakovatelnß (*
). Nap°φklad
<!ELEMENT em (#PCDATA, sub, sup)*> <!ELEMENT sub (#PCDATA)> <!ELEMENT sup (#PCDATA)>
Dokument pak m∙₧e obsahovat nßsledujφcφ text vyhovujφcφ DTD:
<em>Pozor na lφh - C<sub>2</sub>H<sub>5</sub>OH.</em>
Mßme za sebou ·vod do tvorby tΘ Φßsti DTD, kterß definuje pou₧itelnΘ elementy. P°φÜt∞ se podφvßme na to, jak k element∙m p°idat atributy. PotΘ si ji₧ ukß₧eme, jak m∙₧eme pomocφ parseru kontrolovat sprßvnost naÜich dokument∙.
Pou₧itφ ve°ejn²ch identifikßtor∙ mß mnohΘ v²hody. Aby jsme je mohli
pou₧φt, musφme mφt na svΘm poΦφtaΦi lokßlnφ kopie vÜech soubor∙ DTD,
kterΘ pou₧φvßme. V souboru catalog
pak musφme mφt
k dispozici mapovßnφ mezi ve°ejn²mi identifikßtory a
soubory. Mßme-li nap°φklad DTD ulo₧ena v adresß°i
c:\dtd
, budeme mφt pro DocBook v katalogovΘm souboru
°ßdek
PUBLIC "-//OASIS//DTD DocBook V3.1//EN" "c:\dtd\docbook.dtd"
Aby vÜechny aplikace katalogov² soubor naÜly, musφme jeho umφst∞nφ
ulo₧it do prom∞nnΘ prost°edφ SGML_CATALOG_FILES
.
Samotn² v²znam jednotliv²ch Φßsti ve°ejnΘho identifikßtoru vychßzφ
z SGML. Prvnφ znak '-
' znamenß, ₧e identifikßtor nenφ
zaregistrovßn. Znamenß to, ₧e nenφ zaruΦena jeho celosv∞tovß
jednoznaΦnost. Pro registrovanΘ identifikßtory se na tomto mφst∞
pou₧φvß znak '+
'. Pokud je vlastnφkem organizace ISO,
uvßdφ se na zaΦßtku °et∞zec ISO 8879:1986
.
DalÜφ Φßst identifikßtoru oznaΦuje organizaci nebo osobu, kterß je vlastnφkem souboru oznaΦenΘho ve°ejn²m identifikßtorem. Nap°φklad pro HTML mß identifikßtor tvar
-//W3C//DTD HTML 4.0 Transitional//EN
Na prvnφ pohled vidφme, ₧e vlastnφkem je konsorcium W3C. U DocBooku je to zase firma Oasis.
Za dalÜφmi dv∞ma lomφtky nßsleduje urΦenφ typu souboru. V naÜem
p°φpad∞ tam bude v₧dy DTD, proto₧e se odkazujeme na soubor s DTD. PotΘ
nßsleduje textovΘ oznaΦenφ dokumentu -- nap°φklad DocBook
V3.1
pro verzi 3.1 systΘmu DocBook. Za poslednφmi dv∞ma lomφtky
je k≤d jazyka, ve kterΘm je DTD zapsßno. NejΦast∞ji se setkßme s k≤dem
EN
, kter² odpovφdß angliΦtin∞.