Problém: stejné jméno, jiný význam
XML si nechává názvy značek na autorovi, takže se snadno stane, že dva slovníky použijí stejné
jméno pro něco úplně jiného. Nábytkářský katalog má <table> pro stůl, HTML
pro tabulku:
<!-- nabídka nábytku -->
<table>
<name>Jídelní stůl</name>
<width>160</width>
</table>
<!-- HTML tabulka -->
<table>
<tr><td>Jídelní stůl</td></tr>
</table>
Dokud má každý slovník svůj soubor, nic se neděje. Jakmile je ale potřeba vložit HTML popis do
katalogu, program už nepozná, který <table> je který.
Řešení: jmenný prostor a prefix
Jmenný prostor (namespace) je identifikátor slovníku ve tvaru URI. Atributem
xmlns:prefix="URI" se URI přiřadí krátký prefix, kterým se pak označí jména
elementů:
<n:nabidka xmlns:n="https://example.cz/nabytek"
xmlns:h="http://www.w3.org/1999/xhtml">
<n:table>
<n:name>Jídelní stůl</n:name>
</n:table>
<h:table>
<h:tr><h:td>Jídelní stůl</h:td></h:tr>
</h:table>
</n:nabidka>
Teď je jednoznačné, že n:table patří do nábytkového slovníku a
h:table do XHTML. Parser každý element chápe jako dvojici
{URI} + lokální jméno, tedy {https://example.cz/nabytek}table a
{http://www.w3.org/1999/xhtml}table.
URI se nikam nenačítá. Je to jen jedinečný řetězec; na adrese nemusí nic
být. Používají se URL, protože doménu vlastní konkrétní autor, a kolize je tak
nepravděpodobná. Porovnává se znak po znaku — http:// a https:// nebo
lomítko navíc na konci jsou různé jmenné prostory.
Výchozí jmenný prostor
Psát prefix ke každé značce je zdlouhavé, proto existuje výchozí jmenný prostor
deklarovaný atributem xmlns="URI" bez prefixu. Platí pro element, na kterém je
deklarovaný, i pro všechny jeho potomky bez prefixu. Tak je napsaná třeba každá mapa webu:
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://www.example.cz/</loc>
</url>
</urlset>
Všechny tři elementy — urlset, url i loc — jsou v
jmenném prostoru sitemap, přestože nemají prefix. Na tom, jaký prefix (nebo žádný) autor
zvolí, nezáleží; dva dokumenty s různými prefixy a stejným URI jsou z pohledu jmenných
prostorů totožné.
Platnost deklarace
Deklarace platí od elementu, na kterém je zapsaná, pro celý jeho podstrom. Uvnitř ji lze
přepsat jinou deklarací a výchozí jmenný prostor lze zrušit prázdným xmlns="":
<katalog xmlns="https://example.cz/katalog">
<produkt kod="A1">
<nazev>Hrnek</nazev>
<popis xmlns="http://www.w3.org/1999/xhtml">
<p>Keramický hrnek <b>0,3 l</b></p>
</popis>
</produkt>
<poznamka xmlns="">bez jmenného prostoru</poznamka>
</katalog> katalog,produktanazevjsou v prostoru katalogu,popis,pabjsou v prostoru XHTML,poznamkanení v žádném jmenném prostoru.
Atributy a jmenné prostory
Tady chybuje skoro každý: výchozí jmenný prostor se na atributy nevztahuje. Atribut bez prefixu nepatří do žádného jmenného prostoru; chápe se jako vlastnost svého elementu. Do jmenného prostoru se atribut dostane jen s prefixem:
<k:produkt xmlns:k="https://example.cz/katalog"
xmlns:x="https://example.cz/export"
kod="A1" x:priorita="vysoka"/>
Atribut kod je bez jmenného prostoru, x:priorita patří do prostoru
exportu. Typické atributy s prefixem jsou xml:lang, xml:space nebo
xsi:schemaLocation.
Prefixy xml a xmlns jsou vyhrazené. Prefix xml je vždy
svázaný s http://www.w3.org/XML/1998/namespace a nemusí se deklarovat.
Jmenné prostory v XPath a v kódu
Nejčastější dotaz v diskusích zní: „proč mi XPath /urlset/url/loc nic nenajde?“
V XPath 1.0 jméno bez prefixu vždy znamená element bez jmenného prostoru. Elementy
sitemapy ale v prostoru jsou (výchozím), takže se výrazu neshodují. Diagnostiku a kód pro
jednotlivé jazyky shrnuje stránka XPath nic
nevrací.
Řešením je v programu zaregistrovat prefix (třeba s pro URI sitemap) a psát
/s:urlset/s:url/s:loc, nebo se jmenným prostorům vyhnout funkcí
/*[local-name()='urlset']. XPath 2.0 a novější umožňují nastavit výchozí jmenný
prostor pro dotazy. Podrobnosti v kapitole XPath.
Jmenné prostory běžných formátů
URI se musí opsat přesně, včetně protokolu a lomítek:
| Formát | URI jmenného prostoru |
|---|---|
| XHTML | http://www.w3.org/1999/xhtml |
| SVG | http://www.w3.org/2000/svg |
| XSLT | http://www.w3.org/1999/XSL/Transform |
| XML Schema | http://www.w3.org/2001/XMLSchema |
| XML Schema instance (xsi) | http://www.w3.org/2001/XMLSchema-instance |
| Atom | http://www.w3.org/2005/Atom |
| Sitemap | http://www.sitemaps.org/schemas/sitemap/0.9 |
| SOAP 1.1 obálka | http://schemas.xmlsoap.org/soap/envelope/ |
QName, NCName a rezervované prefixy
NCName je XML název bez dvojtečky. QName je buď NCName, nebo dvojice prefix:lokální-název. Rozšířený název elementu tvoří URI prostoru a lokální část; prefix je jen zkratka platná v kontextu.
a:polozka a b:polozka se stejným URI označují stejný rozšířený název. Stejný prefix s jiným URI naopak stejný význam nezaručuje. URI se porovnává jako řetězec, ne po stažení nebo normalizaci adresy.
Prefix xml je rezervovaný pro http://www.w3.org/XML/1998/namespace, xmlns pro deklarace prostorů. Atributy xml:* nevyžadují ruční deklaraci prefixu xml. Výchozí prostor se nevztahuje na neprefixované atributy.
<r xmlns="urn:r" id="1" xmlns:a="urn:a" a:id="2"/> Atribut id nemá prostor, a:id má prostor urn:a. Oba jsou povolené. Dva atributy se stejným URI a lokálním názvem by byly chyba, i kdyby používaly různé prefixy.