DTD -- lekce druhß

Ji°φ Kosek ml.

Deklarace atribut∙

V XML m∙₧e mφt ka₧d² element libovolnΘ mno₧stvφ atribut∙. Atributy se v∞tÜinou pou₧φvajφ pro p°idßnφ r∙zn²ch metainformacφ k element∙m.

Definice atribut∙ pro element mß pom∞rn∞ jednoduch² tvar:

<!ATTLIST jmΘno_elementu deklarace atribut∙>

Deklarace jednotliv²ch atribut∙ se sklßdß ze t°φ Φßstφ. Prvnφ Φßstφ je jmΘno atributu. Pro jmΘna atribut∙ platφ stejnß omezenφ jako pro jmΘna element∙. Atributy jsou rovn∞₧ citlivΘ na velikost pφsmen, a tak MujAtribut a MUJATRIBUT jsou dva zcela rozdφlnΘ atributy.

Za jmΘnem nßsleduje typ atributu. Poslednφ Φßst urΦuje standardnφ hodnotu atributu, pop°φpad∞, zda je pou₧φvßnφ atributu u danΘho elementu povinnΘ. Deklarace atributu se opakuje pro ka₧d² atribut, kter² mß b²t u elementu k dispozici.

Nejobecn∞jÜφm typem atributu je CDATA, kter² umo₧≥uje jako hodnotu atributu zadat libovoln² textov² °et∞zec. Po deklaraci

<!ATTLIST kniha autor CDATA ...>  

M∙₧eme v dokumentu pou₧φvat atribut autor nßsledovn∞

<kniha autor="Karel ╚apek">

Mnohem restriktivn∞jÜφm typem ne₧ CDATA je NMTOKEN. Atribut tohoto typu m∙₧e obsahovat jedno slovo, kterΘ se sklßdß z pφsmen, Φφslic a n∞kolika dalÜφch specißlnφch znak∙.

M∙₧eme pou₧φt i typ NMTOKENS. Atribut pak m∙₧e obsahovat n∞kolik slov vyhovujφcφch typu NMTOKEN odd∞len²ch mezerou.

<!ATTLIST dokument format NMTOKEN ...
                   okraje NMTOKENS ...>

V dokumentu pak m∙₧eme pou₧φt element dokument nap°φklad takto:

<dokument format="A4" okraje="2cm 3cm 2.5cm 3cm">
	...
</dokument>

Mezi dalÜφ typy atribut∙ pat°φ ID, IDREF a IDREFS, kterΘ se pou₧φvajφ pro vytvß°enφ odkaz∙ v rßmci dokumentu. Podrobn∞ji si o nich povφme v n∞kterΘ z dalÜφch Φßstφ serißlu v∞novanΘ odkaz∙m mezi XML-dokumenty.

DalÜφ dva typy jsou ENTITY a ENTITIES, kterΘ pou₧ijeme v p°φpadech, kdy atribut obsahuje jmΘno (resp. jmΘna) entity. Entitßm se budeme rovn∞₧ v∞novat samostatn∞.

DalÜφm typem atributu, na kter² dnes jeÜt∞ nedojde, je NOTATION. Atributy NOTATION slou₧φ k urΦenφ typu dat, kterΘ obsahuje element, pokud se nejednß o XML-data.

Poslednφ mo₧nostφ, jak vymezit typ atributu, je uvedenφ v²Φtu p°φpustn²ch hodnot atributu. Nap°.:

<!ATTLIST obrazek zarovnani (vlevo | vpravo | doprostred) ... >

U elementu obrazek nynφ m∙₧eme jako hodnotu atributu zarovnani uvΘst pouze jedno ze slov vlevo, vpravo a doprostred.

V deklaraci vÜech atribut∙ jsme zatφm na poslednφm mφst∞ pou₧φvali t°i teΦky. Na tomto mφst∞ se uvßdφ standardnφ hodnota atributu nebo to, zda je atribut povinn².

Pokud je atribut povinn², uvede se za deklaracφ jeho typu slovo #REQUIRED. Parser p°i kontrole dokumentu ohlßsφ chyby v₧dy, kdy₧ nebude tento atribut u elementu pou₧it. XML-editor si m∙₧e zadßnφ hodnoty atributu vynutit p°φmo p°i vlo₧enφ elementu, kter² povinn² atribut obsahuje.

OpaΦn²m p°φpadem je situace, kdy m∙₧eme atribut vynechat, a v tomto p°φpad∞ si jeho hodnotu podle sv²ch pot°eb domyslφ sama konkrΘtnφ aplikace, kterß prßv∞ s dokumentem pracuje. V t∞chto p°φpadech se pou₧ije klφΦovΘ slovo #IMPLIED.

DalÜφ mo₧nostφ je specifikovßnφ standardnφ hodnoty. StaΦφ ji uvΘst. Pokud chceme, aby byl obrßzek zarovnßn vlevo, pokud nenφ urΦeno jinak, pou₧ijeme deklaraci:

<!ATTLIST obrazek zarovnani (vlevo | vpravo | doprostred) "vlevo" >

Deklarace element∙ a atribut∙ je zßkladem ka₧dΘho DTD. To m∙₧e obsahovat jeÜt∞ dalÜφ prvky, i kdy₧ u₧ to nenφ tak ΦastΘ. Pokud navrhujeme n∞jakß slo₧it∞jÜφ DTD mohou se nßm hodit tzv. parametrickΘ entity, kterΘ umo₧≥ujφ zkrßtit a zefektivnit zßpis.

ParametrickΘ entity

V DTD Φasto opakujeme stejnΘ sekvence textu. V praxi nap°. mφvajφ vÜechny elementy n∞kolik spoleΦn²ch atribut∙. Je pak zbyteΦnΘ znovu a znovu opisovat deklaraci t²ch₧ atribut∙. Prßci nßm mohou usnadnit parametrickΘ entity. Pomocφ zßpisu

<!ENTITY % entita "n∞jak² text">

Definujeme parametrickou entitu, na kterou se v DTD budeme odvolßvat pomocφ zßpisu %entita;. Pou₧itφ parametrickΘ entity z funkΦnφho hlediska odpovφdß napsßnφ celΘho textu, kter² entita zastupuje, Üet°φ se vÜak prßce. Nßsleduje ukßzka definice parametrickΘ entity %spolecne-atributy;:

<!ENTITY % spolecne-atributy 
	"jazyk	CDATA 	#IMPLIED
	 utajeni (verejne|tajne|prisne-tajne) 'verejne'">

<!ELEMENT clanek	(nazev, autor?, p*)>
<!ATTLIST clanek	%spolecne-atributy;>
<!ELEMENT nazev	(#PCDATA)>
<!ATTLIST nazev	%spolecne-atributy;>
<!ELEMENT autor	(#PCDATA)>
<!ATTLIST autor  	%spolecne-atributy;>
<!ELEMENT p  	(#PCDATA)>
<!ATTLIST p  	%spolecne-atributy;
          id 	ID 	#REQUIRED>

V ukßzkovΘm DTD deklarujeme elementy clanek, nazev, autor a p. VÜechny elementy p°itom majφ atributy jazyk a utajeni. Element p mß navφc jeÜt∞ atribut id. Kdybychom nevyu₧ili parametrickΘ entity, byl by zßpis mnohem delÜφ a jeho pozd∞jÜφ modifikace by byla nßroΦn∞jÜφ.

<!ELEMENT clanek (nazev, autor?, p*)>
<!ATTLIST clanek 
	 jazyk 	CDATA 	#IMPLIED
	 utajeni (verejne|tajne|prisne-tajne) 'verejne'>
<!ELEMENT nazev   (#PCDATA)>
<!ATTLIST nazev  
	 jazyk 	CDATA 	#IMPLIED
	 utajeni (verejne|tajne|prisne-tajne) 'verejne'>
<!ELEMENT autor   (#PCDATA)>
<!ATTLIST autor  
	 jazyk 	CDATA 	#IMPLIED
	 utajeni (verejne|tajne|prisne-tajne) 'verejne'>
<!ELEMENT p	(#PCDATA)>
<!ATTLIST p 
	 jazyk 	CDATA 	#IMPLIED
	 utajeni (verejne|tajne|prisne-tajne) 'verejne'
	 id 	ID 	#REQUIRED>

Kontrola dokumentu oproti DTD

V²hoda uklßdßnφ dokument∙ v XML spoΦφvß p°edevÜφm v mo₧nosti zachytit pomocφ element∙ strukturu dokumentu. Zßkladnφm nßstrojem, kter² se p°i prßci s XML dokumenty pou₧φvß, je parser. Parser je program, kter² kontroluje, zda je dokument sprßvn∞ strukturovan². LepÜφ parsery zßrove≥ kontrolujφ, zda dokument odpovφdß danΘmu DTD (samoz°ejm∞ jen pokud DTD pro dokument existuje).

Parsery dnes existujφ ve dvou podobßch. Tou prvnφ jsou knihovny pro r∙znΘ programovacφ jazyky, kterΘ m∙₧eme vyu₧φvat v naÜich programech. Parser nßm pak krom∞ detekce chyb v dokumentu umo₧nφ velmi snadnΘ Φtenφ dat z XML dokument∙. K tomu, jak parser vyu₧φt z pohledu programßtora, se jeÜt∞ podrobn∞ji vrßtφme v n∞kterΘm z dalÜφch dφl∙. Pro nßs je nynφ d∙le₧itΘ, ₧e v∞tÜina parser∙ existuje i v podob∞ jednoduch²ch program∙, kter²m na vstup p°edßme XML dokument, a na v²stupu obdr₧φme p°φpadn² p°ehled chyb v dokumentu.

Parser vyu₧ijeme zejmΘna v situaci, kdy chceme ov∞°it, zda nßÜ dokument neobsahuje n∞jakΘ syntaktickΘ a strukturnφ chyby. Tato situace m∙₧e nastat v p°φpad∞, kdy dokument vytvß°φme v editoru, kter² nemß podporu XML a umo₧nφ nßm vytvo°it chybn² dokument. Dnes je k dispozici mnoho parser∙ napsan²ch v r∙zn²ch programovacφch jazycφch. Velice populßrnφ platformou pro psanφ parser∙ je jazyk Java. Z hlediska v²konu jsou vÜak dnes lepÜφ parsery napsanΘ v jazyce C++. Pou₧it² jazyk nßs vÜak jako u₧ivatele nemusφ a₧ zas tak moc zajφmat, d∙le₧itß je funkΦnost.

Za jeden z nejlepÜφch parser∙ se dnes pova₧uje parser SP od Jamese Clarka. SP je k dispozici zdarma vΦetn∞ zdrojov²ch text∙, pracuje ve Windows i na Unixu (dokonce existuje i verze pro MS-DOS). Jeho kvality doklßdß i to, ₧e se stal zßkladem mnoha komerΦnφch parser∙, kterΘ jsou prodßvanΘ za velkΘ penφze. SP byl p∙vodn∞ parser vyvinut² pro jazyk SGML, ale od verze 1.3 podporuje i XML. Nic nßm nebrßnφ v jeho vyu₧itφ.

SP si m∙₧ete stßhnout ze serveru www.jclark.com. Pro spuÜt∞nφ SP ve Windows budete konkrΘtn∞ pot°ebovat soubor ftp://ftp.jclark.com/pub/win32/sp1_3.zip. Soubor rozbalφme nap°φklad do adresß°e c:\sp. Pokud si chceme usnadnit spouÜt∞nφ parseru, p°idßme si do prom∞nnΘ PATH cestu c:\sp\bin.

Samotn² parser je realizovßn programem nsgmls. P°ed jeho spuÜt∞nφm musφme nastavit jeÜt∞ n∞kolik prom∞nn²ch prost°edφ, aby sprßvn∞ pracovala podpora XML. Prom∞nnß SP_CHARSET_FIXED musφ b²t nastavena na hodnotu YES. Prom∞nnß SP_ENCODING by m∞la mφt hodnotu XML. Jeliko₧ zatφm nenφ k dispozici mnoho editor∙, kterΘ by p°φmo podporovaly k≤dovßnφ UTF-8, kterΘ je v XML preferovßno, je lepÜφ prom∞nnou SP_ENCODING nastavit na hodnotu windows, resp. iso-8859-2 v Unixu. Pro psanφ XML dokument∙ pak m∙₧eme pou₧φt libovoln² textov² editor. Poslednφ prom∞nnou, kterou musφme nastavit, je SGML_CATALOG_FILES. Do prom∞nnΘ musφme ulo₧it cestu k souboru xml.soc -- nap°. c:\sp\pubtext\xml.soc.

Nynφ si vytvo°φme dokument, kter² budeme parserem kontrolovat. Dejme tomu, ₧e vytvo°φme dokument, kter² vyhovuje DTD, kterΘ jsme p°ed chvφlφ pou₧ili jako p°φklad pro parametrickΘ entity. DTD ulo₧φme do souboru clanek.dtd. NßÜ testovacφ dokument pokus.xml m∙₧e b²t t°eba takov²to:

<!DOCTYPE clanek SYSTEM "clanek.dtd">
<clanek>
<nazev>O myÜφch bez lidφ</nazev>
<p>MyÜi mo₧nß nejsou tak...</p>
<p>MyÜlenka, ₧e myÜi ovlßdajφ...</p>
</clanek>

Pomocφ p°φkazu

nsgmls -wxml -s pokus.xml

spustφme parser. Pokud je nßÜ dokument dob°e strukturovan² a vyhovuje zadanΘmu DTD, neohlßsφ parser ₧ßdnou chybu. Zkuste v dokumentu zßm∞rn∞ ud∞lat n∞jakou chybu (zapome≥te ukonΦovacφ tag, p°ek°i₧te tagy, pou₧ijte neexistujφcφ atribut apod.) a uvidφte, jak vßm o tom podß nsgmls zprßvu.

Pokud mßme XML dokument, ke kterΘmu neexistuje DTD, m∙₧eme jej pomocφ nsgmls takΘ zkontrolovat. StaΦφ pou₧φt parametr -wno-valid a u dokumentu bude pouze kontrolovßno, zda je sprßvn∞ strukturovan² (well-formed).

© Ji°φ Kosek 1999