XML pro web aneb od teorie k praxi, 8.díl - jmenné prostory a XHTML

Důležitým mechanizmem, který umožňuje zabránit konfliktům mezi různými formáty založenými na XML, jsou jmenné prostory. Chcete-li se dozvědět vše důležité o jmenných prostorech a naučit se je používat pro začlenění vlastních elementů do (X)HTML stránek, pak neváhejte pokračovat ve čtení.

K čemu jsou jmenné prostory?

Rozšiřitelnost jazyka XML nám dává prostor vytvářet si vlastní formáty založené na XML pro libovolné použití. Umožňuje nám také využití jiných podobných formátů a jejich úpravu pro dosažení specifického účelu. Můžeme si tak deklarovat jakékoliv elementy a atributy a používat je v určitém významu. V rámci námi navrženého formátu snadno dosáhneme toho, aby zvolené názvy byly jedinečné a jednoznačné.

Problém však nastane například tehdy, pokusíme-li se spojit dva formáty založené na XML a použít je v jednom dokumentu, a stane se, že každý z těchto formátů obsahuje element se stejným názvem, ale jiným významem. Co teď? Můžeme samozřejmě jeden z elementů přejmenovat, ale to si můžeme dovolit jen tehdy, pokud jsme sto ovlivnit i způsob zpracování XML dokumentu a potažmo jednotlivých XML formátů. Ve většině případů by takový krok byl velice nepraktický a vedoucí k dalším možným komplikacím. Například budeme potřebovat přidat další XML formát, který bude znovu obsahovat element stejného jména...

Právě tento problém, tj. potenciální vznik konfliktů při vytváření různých formátů, řeší jmenné prostory (namespaces). Jmenné prostory mají normativní status W3C Recommendation a jejich oficiální specifikaci lze najít na adrese http://www.w3.org/TR/REC-xml-names/.

Práce se jmennými prostory

Výchozí jmenný prostor

Základní použití jmenných prostorů je poměrně jednoduché - pomocí speciálního atributu xmlns deklarujeme výchozí jmenný prostor. Hodnotou tohoto atributu je URI, nejčastěji URL (unikátní internetová adresa). Například:

<report xmlns="http://dataformat.meteoweb.cz/wind/">

Element report je tímto zařazen do jmenného prostoru, který je jednoznačně identifikován pomocí URL http://dataformat.meteoweb.cz/wind/. Není důležité, jestli na této adrese je popis našeho XML formátu, nebo tam není vůbec nic - důležité je, že tato adresa je správně vytvořena a sama jedinečným způsobem identifikuje náš XML formát (tj. není použita pro identifikaci jiného XML formátu).

Výchozí jmenný prostor, který jsme použili pro element, se vztahuje také na všechny jeho potomky, pokud není kterýkoliv z těchto potomků explicitně zařazen do jiného jmenného prostoru.

<report xmlns="http://dataformat.meteoweb.cz/wind/">
	<wdir>260</wdir>
	<wspd>6</wspd>
	<temp_report xmlns="http://dataformat.meteoweb.cz/temperature/">
		<temp>-6.8</temp>
	</temp_report>
</report>

Ve výše uvedeném příkladu patří elementy wdir a wspd do stejného jmenného prostoru, jako element report. Element temp_report má již deklarován jmenný prostor odlišný - tento nový jmenný prostor platí i pro element temp.

Zrušení výchozího jmenného prostoru

Pokud potřebujeme, aby určitý element, který je potomkem jiného elementu s deklarovaným výchozím jmenným prostorem, nebyl zařazen do žádného jmenného prostoru, stačí uvést u tohoto elementu práznou hodnotu atributu xmlns:

<report xmlns="http://dataformat.meteoweb.cz/wind/">
	<wdir>260</wdir>
	<wspd>6</wspd>
	<temp_report xmlns="">
		<temp>-6.8</temp>
	</temp_report>
</report>

Element temp_report i se všemi potomky (v našem příkladu má tento element pouze jediného potomka) nyní nepatří do žádného jmenného prostoru.

Předpona jmenného prostoru

Velmi často se u jmenných prostorů setkáváme s předponami jmenného prostoru (namespace prefix). Předpony jmenného prostoru využijeme zejména tehdy, kombinujeme-li více jmenných prostorů dohromady a museli bychom pro "každý druhý" element deklarovat jmenný prostor.

Deklarace předpony jmenného prostoru využívá také atributu xmlns, ovšem ke jménu tohoto atributu za dvojtečku je nutné připojit předponu jmenného prostoru. Tuto předponu pak můžeme přidat před jméno elementu.

<wnd:report xmlns:wnd="http://dataformat.meteoweb.cz/wind/">

Deklarovali jsme jmenný prostor svázaný s předponou (prefixem) wnd. U kteréhokoliv potomka tohoto elementu můžeme tuto předponu použít jako identifikátor zastupující jmenný prostor. Při tomto způsobu deklarace musíme předponu vložit i do jména elementu, u kterého tento jmenný prostor deklarujeme. Důvod je v tom, že takto deklarovaný jmenný prostor se implicitně nevztahuje na příslušný element a jeho potomky, ale pouze na elementy, které jsou opatřeny deklarovanou předponou. Z toho vyplývá, že u vhodného elementu (nejčastěji kořenového) můžeme deklarovat více jmenných prostorů a jejich předpon najednou. Předpony pak využijeme u kteréhokoliv z vnořených elementů, který potřebujeme vztáhnout pod jeden z těchto jmenných prostorů.

<wnd:report wnd:xmlns="http://dataformat.meteoweb.cz/wind/" xmlns:tmp="http://dataformat.meteoweb.cz/temperature/">
	<wnd:wdir>260</wnd:wdir>
	<wnd:wspd>6</wnd:wspd>
	<tmp:temp_report>
		<tmp:temp>-6.8</tmp:temp>
	</tmp:temp_report>
</wnd:report>

V předchozím příkladu jsme deklarovali dva jmenné prostory a jejich předpony - wnd a tmp. Předpony jsou pak použity u každého elementu pro identifikaci jeho jmenného prostoru.

Oba způsoby deklarace jmenných prostorů můžeme kombinovat - u jednoho elementu tak lze deklarovat jak výchozí jmenný prostor, který se pak bude vztahovat i na všechny vnořené elementy bez explicitní deklarace jiného jmenného prostoru, tak i další jmenné prostory prostřednictím prefixu.

<report xmlns="http://dataformat.meteoweb.cz/wind/" xmlns:tmp="http://dataformat.meteoweb.cz/temperature/">
	<wdir>260</wdir>
	<wspd>6</wspd>
	<tmp:temp_report>
		<tmp:temp>-6.8</tmp:temp>
	</tmp:temp_report>
</report>

Předpony jmenného prostoru mohou mít stejné jméno, a přesto mohou ukazovat na jiný jmenný prostor. Viz následující příklad:

<wnd:report wnd:xmlns="http://dataformat.meteoweb.cz/wind/">
	<wnd:wdir>260</wnd:wdir>
	<wnd:wspd>6</wnd:wspd>
	<wnd:temp_report xmlns:wnd="http://dataformat.meteoweb.cz/temperature/">
		<wnd:temp>-6.8</wnd:temp>
	</wnd:temp_report>
</wnd:report>

U elementu temp_report byl jmenný prostor s předponou wnd "předeklarován" a v kontextu tohoto elementu a jeho potomků označuje odlišný jmenný prostor. I tato skutečnost je důsledkem pravidla, že jmenný prostor je jednoznačně identifikován pomocí URI v hodnotě atributu xmlns, nikoliv předponou jmenného prostoru. Toto pravidlo platí i případě, kdy deklarujeme rozdílné předpony jmenného prostoru, ale přiřadíme jim stejné URI:

<wnd:report wnd:xmlns="http://dataformat.meteoweb.cz/wind/" xmlns:tmp="http://dataformat.meteoweb.cz/wind/">
	<wnd:wdir>260</wnd:wdir>
	<wnd:wspd>6</wnd:wspd>
	<tmp:temp_report>
		<tmp:temp>-6.8</tmp:temp>
	</tmp:temp_report>
</wnd:report>

V tomto případě patří všechny elementy do stejného jmenného prostoru, ačkoliv předpony mají rozdílná jména!

Jmenné prostory a atributy

Atributy nikdy nepatří do žádného jmenného prostoru, pokud jim není jmenný prostor explicitně přiřazen prostřednictvím předpony jmenného prostoru.

<wnd:report wnd:xmlns="http://dataformat.meteoweb.cz/wind/" xmlns:tmp="http://dataformat.meteoweb.cz/temperature/">
	<wnd:wdir unit="degree">260</wnd:wdir>
	<wnd:wspd wnd:unit="m/s" tmp:windcool="-10">6</wnd:wspd>
</wnd:report>

V tomto případě nemá atribut unit u elementu wdir přiřazen žádný jmenný prostor, kdežto atribut stejného jména u elementu wspd již do jmenného prostoru patří. Atribut může být samozřejmě přiřazen do jiného jmenného prostoru, než element, u kterého se atribut vyskytuje - to ukazuje atribut windcool.

Jmenné prostory a DTD

Pokud vytváříme platné XML dokumenty s DTD, musí být deklarace typu elementu uvedeny včetně předpony jmenného prostoru. Rovněž atribut xmlns je potřeba deklarovat v DTD. Pomocí mechanizmu deklarace výchozí hodnoty atributu je možné takto deklarovat i hodnotu atributu xmlns a tím i implicitní jmenný prostor. Stejně tak je možné v DTD atributu xmlns přiřadit fixní hodnotu. Při těchto operacích se ovšem vyvarujte toho, aby deklarace výchozích hodnot atributu xmlns byly umístěny v externím subsetu DTD - nedojde-li z různých důvodů k načtení externího DTD, může to výrazným způsobem zasáhnout do obsahu a způsobu čtení XML dokumentu!

Použití jmenných prostorů pro přidání vlastních elementů do (X)HTML

Dobrou zprávou je, že jmenné prostory podporují i nejrozšířenější prohlížece - Internet Explorer, Mozilla, Opera. Špatnou zprávou je, že Internet Explorer zvládne pouze vymezenou část standardu XML namespaces. Ukážeme si tedy, jaké zásady je nutné dodržet, abychom za pomoci deklarace jmenných prostorů mohli používat vlastní elementy v (X)HTML stránce, a aby to bylo funkční ve všech třech výše uvedených prohlížečích.

  1. Jmenný prostor musí být deklarován pomocí předpony u elementu html.

    Všechny jmenné prostory, které hodláte v (X)HTML dokumentu používat, deklarujte u kořenového elementu. U platné XHTML stránky by měl být u tohoto elementu deklarován i výchozí jmenný prostor pro XHTML. Kořenový element tedy může vypadat například takto:

    <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wnd="http://dataformat.meteoweb.cz/wind/">

    Jmenných prostorů může být u elementu html deklarováno samozřejmě i více.

  2. Vlastní element můžete použít v (X)HTML dokumentu spolu s deklarovanou předponou.
    <p>běžný odstavec</p>
    <wnd:wdir>260</wnd:wdir>
    <wnd:wspd>6</wnd:wspd>
    <wnd:p>element p s jiným namespace přestává být XHTML elementem...</wnd:p>

    Nyní lze v dokumentu používat elementy libovolného jména spolu s předponou jmenného prostoru. Použijete-li předponu jmenného prostoru s běžným (X)HTML elementem, pak tento element přestává být běžným (X)HTML elementem, nýbrž je již prohlížečem identifikován jako váš vlastní element! Např element input, pokud je mu přiřazen jiný jmenný prostor, přestane být formulářovým prvkem!

  3. Jméno elementu lze použít jako selektoru v kaskádovém stylu, musí však být uvedeno včetně předpony jmenného prostoru. Dvojtečka musí mít před sebou zpětné lomítko.

    Elementy s vaším vlastním jmenným prostorem nemají v prohlížeči žádné výchozí formátování - jejich vzhled však lze upravit pomocí kaskádového stylu. Nezapomeňte však v CSS selektoru uvést před dvojtečkou zpětné lomítko, aby nedošlo k záměně s pseudotřídami (např. a:hover).

    <style type="text/css">
    	wnd\:wspd, wnd\:wdir {
    		display: block;
    		font-weight: bold;
    		border: 1px solid red;
    		margin: 5px;
    		padding: 5px;
    	}
    	wnd\:p {
    		display: block;
    		background-color: yellow;
    	}
    </style>

Ukázkový XHTML dokument si můžete prohlédnout. V Mozille a Opeře jsou možnosti jmenných prostorů širší - mimo jiné nám dovolují míchat XML s XHTML i úplně "opačným" způsobem. Malou ukázku těchto možnosti si však necháme až příště. Hlavní náplní příštího dílu však bude vizuální formátovaní XML dokumentů pomocí kaskádových stylů.

Diskuze (1) Další článek: MS zapomněl přidat důležitou opravu do SP1 pro XPčka

Témata článku: , , , , , , , , , , , , , , , , , , , ,