XML jest językiem. Dużo więcej daje jednak spojrzenie na XML jako metajęzyk, to znaczy zbiór języków, zastosowań XML. Na przykład zastosowaniem XML jest XHTML 1.0, to znaczy każdy dokument XHTML jest dokumentem XML, a dodatkowo jest zgodny z defnicją typu dokumentu XHTML.
Do zastosowań XML należą znane standardy, jak XSLT, XHTML czy WSDL. Można także zdefiniować swój własny język – zastosowanie XML. Definiowanie zastosowania XML nazywa się zwykle definiowaniem struktury dokumentu lub typu dokumentu.
Porządna definicja zastosowania XML, analogicznie do definicji języka programowania, powinna zawierać dwie części:
W praktyce formalnie definiuje się jedynie część składniową, służą do tego wymienione poniżej standardy. Natomiast znaczenie elementów i atrybutów opisuje się słownie w oddzielnym dokumencie tekstowym (jak w przypadku rekomendacji W3C), w komentarzach DTD czy schematu, lub niestety nie opisuje w ogóle.
Zalecane sposoby definiowania struktury dokumentu:
Alternatywne standardy (jako ciekawostka):
Obecnie najbardziej zalecanym standardem do definiowania nowych typów dokumentów jest XML Schema. Istnieje jednak wiele typów dokumentów już zdefiniowanych za pomocą DTD, a czasem, ze względu na specyfikę zastosowania i używane narzędzia, DTD opracowuje się (lub generuje się ze schematów) również dla nowych standardów (np. XHTML).
Każdy dokument XML musi być poprawny składniowo (well-formed) – być zgodny z gramatyką XML i spełniać well-formedness constraints wymienione w rekomendacji XML.
Dodatkowo dokument XML może być poprawny strukturalnie (valid) – być zgodny z definicją struktury. Jeśli nie jest powiedziane inaczej, chodzi o DTD, a dokument ma spełniać validity constraints wymienione w rekomendacji XML. Tego samego terminu używa się także do określenia zgodności ze schematem XML Schema bądź innych standardów.
Proces sprawdzania poprawności strukturalnej nazywa się walidacją. Po wykonaniu walidacji mamy pewność, że dokument posiada właściwą strukturę. Dzięki temu, np. we własnych programach czy w arkuszach XSLT, nie musimy już rozważać przypadków błędnych i od razu wiemy, że np. wymagane elementy rzeczywiście występują.
Definicja struktury i proces walidacji mogą mieć wpływ na zawartość dokumentu w warstwie logicznej. Dzieje się tak ponieważ:
xml:space
parser może zignorować niektóre białe znaki między elementami,Deklaracja DTD w dokumencie występuje za deklaracją XML (jeśli istnieje) a przed elementem głównym. Może w całości być zawarta w dokumencie, może być zawarta w encji zewnętrznej, lub częściowo być w encji zewnętrznej, a częściowo w dokumencie - w tym przypadku jako pierwsza przetwarzana jest część wewnętrzna.
<?xml version="1.0"?> <!DOCTYPE greeting SYSTEM "hello.dtd"> <greeting>Hello, world!</greeting>
<?xml version="1.0"?> <!DOCTYPE greeting PUBLIC "-//W3C//GREETEING 1.0//EN" "hello.dtd"> <greeting>Hello, world!</greeting>
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE greeting [ <!ELEMENT greeting (#PCDATA)> ]> <greeting>Hello, world!</greeting>
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE greeting SYSTEM "hello.dtd" [ <!ATTLIST greeting words CDATA #IMPLIED> ]> <greeting words="2">Hello, world!</greeting>
Definiowanie struktury dokumentu w DTD opiera się na założeniu, że w całym dokumencie elementy o tej samej nazwie mają podobną strukturę. DTD definiuje typy elementów, elementami jednego typu są elementy o tej samej nazwie.
DTD pozwala zdefiniować takie własności dokumentu jak:
Dla każdej nazwy elementu może istnieć tylko jedna jego deklaracja w DTD. Deklaracja elementu ma postać:
<!ELEMENT nazwa-elementu typ-zawartości-elementu >
Typy zawartości elementu:
ANY
EMPTY
(#PCDATA)
(#PCDATA | nazwa-elementu1 | nazwa-elementu2 ... )*
( ) , | ? * +
z nazw elementów.Zapisz deklaracje elementów o następujących typach zawartości:
a
lub niezerowa sekwencja par elementów b
i c
,a
lub para elementów b
i c
,a
,a
i b
, ale zaczynający się i kończący na a
(co najmiej jedno a
),a
, od jednego do trzech razy b
, opcjonalnie c
.Czy w DTD da się zapisać następujące typy zawartości? Jeśli tak, to podaj rozwiązanie:
a
,imię
, nazwisko
, nr-indeksu
w podanej tu kolejności,imię
, nazwisko
, nr-indeksu
, ale w dowolnej kolejności,a
, b
i c
, w podanej kolejności kolejności, wszystkie muszą wystąpić dokładnie raz,a
, b
i c
, w dowolnej kolejności, wszystkie muszą wystąpić dokładnie raz,a
, b
i c
, w dowolnej kolejności, wszystkie mogą wystąpić najwyżej raz,a
, b
i c
, w dowolnej kolejności, wszystkie mogą wystąpić co najmniej raz,a
, b
i c
, w dowolnej kolejności, wszystkie mogą wystąpić dowolną liczbę razy (także zero).Deklaracja listy atrybutów ma postać:
<!ATTLIST nazwa-elementu nazwa-atrybutu1 typ-zawartości-atrybutu1 opis-domyślnego1 nazwa-atrybutu2 typ-zawartości-atrybutu2 opis-domyślnego2 ... >
Dla każdego elementu może być wiele list atrybutów, są łączone. Dla każdego atrybutu może być w sumie wiele deklaracji – liczy się pierwsza.
Typy zawartości atrybutu:
CDATA
ID
IDREF
IDREFS
IDREF
, ale może być wiele nazw rozdzielonych białymi znakamiNMTOKEN
, NMTOKENS
-
_
.
:
.(token1 | token2 ...)
ENTITY
, ENTITIES
, NOTATION
opis-domyślnego
określa czy atrybut jest wymagany i jaką ma wartość domyślną:
#REQUIRED
#IMPLIED
"wartość-domyślna"
#FIXED "wartość-domyślna"
Zapisz deklaracje atrybutów:
Ala ma kota
,mały
, średni
, duży
.Czy w DTD da się zapisać następujące typy atrybutów? Jeśli tak, to podaj rozwiązanie. Być może jest rozwiązanie zbliżone?
Encja ma swoją nazwę i wartość – fragment dokumentu. Aby można było użyć danej encji, trzeba ją zadeklarować w DTD (nie dotyczy to pięciu encji predefiniowanych). Procesor XML powinien traktować dokument tak jakby w miejsce referencji do encji wstawił ich wartości.
Referencja do encji ogólnej w dokumencie ma postać &nazwa_encji;
i może wystąpić poza DTD,
natomiast deklaracja w DTD:
<!ENTITY nazwa-encji wartość-encji>
Może być wiele deklaracji encji o tej samej nazwie, liczy się pierwsza.
Wartość encji może być podana bezpośrednio w deklaracji ujęta w znaki "
lub '
,
wtedy encję nazywamy wewnętrzną.
Można też zadeklarować encję zewnętrzną – jest to uogólnienie pliku, jakiś zasób dostępny dla procesora XML. Do identyfikacji encji zewnętrznej służy identyfikator systemowy lub identyfikator publiczny. Encja po wstawieniu jest przetwarzana jako XML, powinna być fragmentem XML dającym się sparsować (jeśli jest znacznik otwierający, powinien być zamykający itp.), ponadto może zaczynać się od deklaracji analogicznej do deklaracji XML, podającej wersję XML i kodowanie. Istieją też encje nieprzetwarzane (tylko zewnętrzne).
<!ENTITY wewnetrzna "bla bla bla <bla>123</bla>">
<!ENTITY zewnetrzna_id_systemowy SYSTEM "http://www.textuality.com/boilerplate/OpenHatch.xml">
<!ENTITY zewnetrzna_id_publiczny PUBLIC "-//Textuality//TEXT Standard open-hatch boilerplate//EN" "http://www.textuality.com/boilerplate/OpenHatch.xml">
<!ENTITY zewnetrzna_nieprzetwarzana SYSTEM "../grafix/OpenHatch.gif" NDATA gif >
Encja parametryczna to specjalny rodzaj encji, do której referencje pojawiać się mogą wewnątrz DTD.
Referencja ma postać: %nazwa_encji;
, natomiast deklaracja:
<!ENTITY % nazwa-encji wartość-encji>
Encje parametryczne też mogą być wewnętrzne i zewnętrzne, ale nie ma nieprzetwarzanych. Encje parametryczna i ogólna o tej samej nazwie są różnymi obiektami, mogą istnieć obok siebie. Encji parametrycznych używa się zwykle w celu zdefiniowania w jednym miejscu typu zawartości, który następnie jest używany dla wielu elementów / atrybutów.
Wszystkie encje muszą być zadeklarowane przed jakimkolwiek odwołaniem do nich.
Zapisz DTD opisujące znane z HTML elementy dla list ol
, ul
, li
.
Załóżmy, że element główny body
może zawierać tekst z zanurzonymi w nim listami,
listy tylko elementy wypunktowania (li
),
a elementy wypunktowania znowu tekst z zanurzonymi listami. W każdym miejscu gdzie dopuszczalny jest tekst,
może być on znakowany elementami font
z atrybutami size
i face
.
Każdy element może zawierać atrybuty id
o typie ID
oraz class
o typie
NMTOKEN
.
Użyj encji parametrycznych, aby uniknąć powtarzających się fragmentów kodu (tj. nie wprowadzać dwa razy takiego samego typu zawartości).
<![INCLUDE[ fragment DTD ]]> <![IGNORE[ fragment DTD ]]>
W połączeniu z encjami parametrycznymi stanowią mechanizm do tworzenia sparametryzowanych DTD.
Zmień napisane wcześniej DTD tak, aby dokumenty napisane do poprzedniej wersji dalej się walidowały,
natomiast nowe z pewną drobną dodatkową informacją były zgodne z nowy standardem,
w którym nie ma elementów font
, a są span
z atrybutem style
. Atrybuty
id
i class
, jak poprzednio, mogą występować we wszystkich elementach.
Użyj sekcji warunkowych i encji parametrycznych.