XML – ćwiczenia 2: DTD

Definiowanie zastosowań XML

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:

  1. składniową – podanie dopuszczalnych nazw elementów i atrybutów, oraz ich dopuszczalnej zawartości,
  2. semantyczną – określenie znaczenia poszczególnych elementów i atrybutów.

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.

Standardy

Zalecane sposoby definiowania struktury dokumentu:

  • DTD (Document Type Definition) – część standardu XML,
  • XML Schema – rekomendacja W3C.

Alternatywne standardy (jako ciekawostka):

  • Relax NG – standard podobny do XML Schema, mniej rozbudowana i bardziej czytelna składnia ułatwia ręczną edycję,
  • Schematron – odmienna ideologia, typ dokumentu określa się tu nie w oparciu o gramatykę, ale poprzez listę predykatów, które dokumenty muszą spełniać.

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).

Dwa stopnie poprawności dokumentu, walidacja

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ż:

  • zarówno DTD jak i schemat XML Schema może określać domyślne wartości atrybutów,
  • na podstawie definicji struktury oraz specjalnego atrybutu xml:space parser może zignorować niektóre białe znaki między elementami,
  • (tylko) DTD może definiować encje, które rozwijają się do określonej zawartości; encje mogą odwoływać się także do zewnętrznych, potencjalnie zmiennych, zasobów.

DTD

Położenie

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.

Przykład 1.

<?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>

Elementy

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:

  • zestaw dopuszczalnych typów elementów (nazwy elementów nie wymienione w DTD nie mogą występować w dokumencie),
  • dla każdego typu elementu pozwala w pewnym stopniu określić jego dopuszczalną zawartość (patrz dalej),
  • dla każdego typu elementu określa jego atrybuty, ich wartości domyślne, obowiązkowość występowania, w pewnym stopniu ich dopuszczalne wartości.

Dla każdej nazwy elementu może istnieć tylko jedna jego deklaracja w DTD. Deklaracja elementu ma postać:

<!ELEMENT element-name element-content-type >

Typy zawartości elementu:

ANY
zawartość dowolna,
EMPTY
element zawsze jest pusty,
#PCDATA
zawartość tekstowa,
(#PCDATA | element1 | element2 ... )*
model mieszany (mixed content) – zawartość tesktowa z zanurzonymi w niej elementami, bez kontroli kolejności ani liczności wystąpień,
wyrażenie regularne
zbudowane za pomocą ( ) , | ? * + z nazw elementów.

Zadanie 1.

Write declarations of elements with the following content types:

  1. a non-empty sequence of elements a or a non-empty sequence of pairs of elements b and c,
  2. a non-empty sequence of choices: one a or a pair of b and c elements,
  3. at least three elements a,
  4. a sequence of arbitrary mixed a and b, starting and ending with a (at least one a).

Zadanie 2.

Which of the following content models can be definded in a DTD? Give solutions:

  1. six to nine elements a,
  2. an arbitrary permutation of elements a, b, and c,
  3. text with elements a, b, and c put in, in the given order, each element occurs exactly once,
  4. text with elements a, b, and c put in, in any order, each element occurs exactly once,
  5. text with elements a, b, and c put in, in any order, each element occurs an arbitrary number of times, including zero,

Atrybuty

Deklaracja listy atrybutów ma postać:

<!ATTLIST nazwa-elementu
	attribute1-name attribute1-content-type occurence-indicator1
	attribute2-name attribute2-content-type occurence-indicator2
	...
>

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
dowolny tekst,
ID
nazwa unikalna w całym dokumencie, dla danego typu elementu tylko jeden atrybut może być zadeklarowany jako ID,
IDREF
nazwa występująca gdzieś w dokumencie jako wartość typu ID,
IDREFS
jak IDREF, ale może być wiele nazw rozdzielonych białymi znakami
NMTOKEN, NMTOKENS
jeden lub wiele rozdzielonych białymi znakami tokenów, czyli napisów złożonych z liter, cyfr, znaków - _ :.
(token1 | token2 ...)
jeden z podanych tu tokenów,
ENTITY, ENTITIES, NOTATION
inne typy.

occurence-indicator określa czy atrybut jest wymagany i jaką ma wartość domyślną:

#REQUIRED
atrybut zawsze musi być określony explicite,
#IMPLIED
atrybut nie musi być podany, nie ma wartości domyślnej,
"default value"
atrybut nie musi być podany, jeśli nie jest, to przyjmowana jest wymieniona tu wartość domyślna,
#FIXED "the only allowed value"
atrybut nie musi być podawany, zawsze ma określoną tu wartość domyślną, nie może w dokumencie występować z inną wartością.

Zadanie 3.

Write declarations of attributes:

  1. any value, optional,
  2. value from list (small, medium, large), required,
  3. value from list as above, default value is medium.

Zadanie 4.

Which of the following attribute types can be definded in a DTD? Give solutions where they exist.

  1. natural number,
  2. a name (in the meaning of XML grammar),
  3. names separated with spaces,
  4. one name from a given set,
  5. a list of names from a given set,
  6. one text string from a given set of strings (the strings may contain spaces).

Encje

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 entity-name entity-value>

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).

Przykład 2.

<!ENTITY internal
         "bla bla bla <bla>123</bla>">
<!ENTITY external_with_system_id
         SYSTEM "http://www.textuality.com/boilerplate/OpenHatch.xml">
<!ENTITY external_with_public_id
         PUBLIC "-//Textuality//TEXT Standard open-hatch boilerplate//EN"
         "http://www.textuality.com/boilerplate/OpenHatch.xml">
<!ENTITY external_unparsed
         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 % entity-name entity-value>

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.

Zadanie 5.

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. Jaki typ atrybutów będzie najbardziej odpowiedni dla HTML-owych id i class? Dodaj takie atrybuty do wszystkich zdefiniowanych elementów.

Użyj encji parametrycznych, aby uniknąć powtarzających się fragmentów kodu (tj. nie wprowadzać dwa razy takiego samego typu zawartości).

(The same task in English) Write a DTD defining elements for lists such as in HTML: ol, ul, li. Assume that body element may contain text with lists within, both kinds of lists may contain only list items (li), and list items may in turn contain text with lists. Wherever text is allowed, it can be marked using font elements having attributes size and face. What types whould you choose for HTML attributes id and class? Add such attributes to all defined elements.

Use parameter entities to avoid code duplication (try not to define the same content type or attributes twice).

Sekcje warunkowe

<![INCLUDE[ DTD fragment ]]>
<![IGNORE[ DTD fragment ]]>

W połączeniu z encjami parametrycznymi stanowią mechanizm do tworzenia sparametryzowanych DTD.

Zadanie 6.

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.

Using parameter entities and conditional sections make a DTD defining two versions of documents.

  • "Old" documents have structure as defined in the previous task, and validate with the DTD without any additional information.
  • "New" documents contain span elements with attribute style instead of deprecated font elements. They validate with the DTD, however, they may contain some additional information.

Valid XHTML 1.1Valid CSS