Tworzenie poprawnego pliku XML

Definiowanie treści dokumentu XML

W dotychczasowych artykułach omawialiśmy podstawowe zasady tworzenia dokumentów XML. Trzecia część, Definiowanie treści dokumentu, będzie trochę bardziej skomplikowana, ponieważ zawiera w sobie więcej informacji z dziedziny informatyki. Najważniejszym krokiem w budowaniu struktury XML jest zdefiniowanie Elementów, które będą wykorzystywane w projekcie. Ogromną rolę w tym procesie pełni architekt struktury, ponieważ to jego zadaniem jest poprawnie i wyczerpująco zdefiniować wszystkie niezbędne Elementy planowanego dokumentu XML. Na tym etapie jest to ściśle praca merytoryczna. Każdy błąd popełniony na początku replikuje się na wszystkich dalszych etapach i może wygenerować setki godzin ręcznej pracy nanoszenia poprawek, a przecież automatyzacja to główny cel wykorzystania XML. Jest więc naprawdę istotne, aby twórca architektury starannie przewidział i zdefiniował Elementy, które będą stanowić podstawę do realizacji i wszechstronnego wykorzystania projektu. W standardzie XML istnieją dwie metody definiowania Elementów dokumentów.

Definiowanie treści w dokumencie DTD

DTD (Document Type Definition) jest plikiem kontrolnym, który definiuje formalną strukturę dokumentu XML. Poprawnemu dokumentowi XML musi towarzyszyć definicja DTD (lub Schemat XML – Schema) i musi on być zgodny ze wszystkimi deklaracjami zawartymi w tej definicji DTD (lub schemacie XML). Istnieją dwa różne sposoby powiązania dokumentów XML z definicjami DTD (lub Schematami XML):

  1. Powiązanie bezpośrednie – w dokumencie XML wpisana jest nazwa definicji DTD w deklaracji DOCTYPE (na przykład <!DOCTYPE root-element SYSTEM "plik_dtd.dtd" >, w którym plik_dtd.dtd jest nazwą pliku DTD. W przypadku Schematu w dokumencie umieszczona jest ścieżka do Schematu XML w atrybucie schemaLocation (na przykład <xsi:schemaLocation="http://www.logoscipt.pl/schemat.xsd">, gdzie schemat.xsd jest nazwą Schematu XML).
  2. Pozycja katalogu XML – pliki definicji DTD lub Schematu XML mogą zostać zarejestrowane w katalogu XML, a następnie powiązane z reprezentującym je kluczem. Odwołując się do klucza pliku definicji DTD lub Schematu XML z poziomu dokumentu XML nie jest konieczne bezpośrednie odwoływanie się do tych plików. Pozycja katalogu XML składa się z dwóch części: klucza (reprezentującego definicję DTD lub Schemat XML) oraz identyfikatora URI (informacja o położeniu definicji DTD lub Schematu XML).

W przeciwieństwie do Schematu XML (schema), który będzie omówiony w dalszej części artykułu, DTD nie ma formy pliku zapisanego w standardzie XML, jest stosunkowo prosty, a w związku z tym ma dość ograniczone możliwości.

W dalszym ciągu artykułu, jako przykład zostanie przytoczona struktura XML słownika, ponieważ jest prosta i łatwa do zrozumienia.

Jeśli dokument XML jest powiązany z definicją DTD, to znajduje się w nim znacznik DOCTYPE typu:
Oto treść hasła „a”, definicja zaczerpnięta z Wikipedii:
A (minuskuła: a) – pierwsza litera alfabetu łacińskiego i alfabetów na nim opartych, w tym alfabetu polskiego.

Kod XML dla tego hasła może wyglądać następująco (może, ponieważ strukturę Elementów tworzy architekt):

<?xml version="1.0"?>
<!DOCTYPE struktura SYSTEM “struktura.dtd”>
<slownik id="15">
<haslo>
<entry>a</entry>
<rozwiniecie>minuskuła: a</rozwiniecie>
<tresc>pierwsza litera alfabetu łacińskiego i alfabetów na nim opartych, w tym alfabetu polskiego.</tresc>
</haslo>
</slownik>

W bardziej skomplikowanej wersji doprecyzowane są dodatkowe dane takie, jak np. odnośniki do innych haseł:

<?xml version="1.0"?>
<!DOCTYPE struktura SYSTEM “struktura.dtd”>
<slownik>
<haslo typ="jezyk" id="000012" pri="10">
<entry>a</entry>
<rozwiniecie>minuskuła: a</rozwiniecie>
<tresc>pierwsza litera <ref target="0220101">alfabetu łacińskiego</ref> i alfabetów na nim opartych, w tym <ref target="0220152">alfabetu polskiego.</ref></tresc>
</haslo>
</slownik>

Dokument DTD opisujący powyższą strukturę przyjąłby następujący wygląd:

<!ELEMENT slownik (haslo+)>
<!ELEMENT haslo (entry, rozwiniecie?, tresc)>
<!ELEMENT entry (#CDATA)>
<!ELEMENT rozwiniecie (#CDATA)>
<!ELEMENT tresc (ref*, #CDATA)>

Element slownik. Definicja określa, że w słowniku musi znajdować się co najmniej jedno hasło. Znak plusa po haśle (haslo+) informuje parser, że w tym elemencie musi być chociaż jedno hasło, ale może też ich być dowolnie dużo.

Element haslo. Definicja określa, że hasło może zawierać po kolei entry (główkę), może (ale nie musi) rozwinięcie, a następnie jedną treść. Znak zapytania na końcu rozwiniecie (rozwiniecie?) oznacza zero lub jedno wystąpienie, ponieważ hasło może nie mieć w ogóle rozwinięcia, ale jeśli ma, to wyłącznie jedno.

Element entry. Formuła (#CDATA) oznacza, że Element zawierają wyłącznie tekst. W treści można jednak umieścić nie tylko czysty tekst, lecz również dowolną liczbę referencji (odniesień) do innych Elementów, przy czym dowolna liczba oznacza od zera do nieskończoności.

Element rozwiniecie. Zgodnie z definicją rozwinięcie może zawierać wyłącznie tekst (#CDATA).

Element tresc. W tym elemencie może się znaleźć tekst (#CDATA), ale również dowolna liczba referencji, czyli odniesień do haseł w tym samym lub innym słowniku.

DTD nie daje możliwości szczegółowego zdefiniowania zawartości Elementów, np. sprecyzowania, że Element <numer_telefonu> może zawierać tylko cyfry, albo że <kod_pocztowy> składa się dokładnie z pięciu cyfr. Niemniej jednak DTD określa, jakie kombinacje Elementów są dopuszczalne. Na przykład próba stworzenia hasła, w którym treść poprzedzałaby tag entry lub hasło nie zawierałaby w ogóle treści, wygeneruje błąd dokumentu XML.

Przykładowe Elementy definicji DTD

<!ELEMENT ksiazka (metadane, rozdzial+|litera+)> Każda książka musi zawierać metadane (np. numer ISBN, numer archiwalny, autora etc.) oraz dzielić się na jeden lub więcej rozdziałów LUB liter. Niedopuszczalne jest mieszanie rozdziałów i liter w jednym pliku.

<!ELEMENT rozdzial (#CDATA, tytul_1*, tytul_2*, tytul_3*, tekst*)> Rozdział może zawierać dowolną liczbę tytułów pierwszego, drugiego i trzeciego rzędu oraz tekst. Mogą nie występować w ogóle, albo może ich być dowolnie dużo.

Definiowanie atrybutów

Kolejny etapem tworzenia struktury dokumentu XML z wykorzystaniem DTD jest zdefiniowanie listy atrybutów przynależnych do każdego Elementu. Poniżej analiza przytoczonego wcześniej przykładu struktury XML słownika (tego bardziej rozbudowanego):

<?xml version="1.0"?>
<!DOCTYPE struktura SYSTEM “struktura.dtd”>
<slownik>
<haslo typ="jezyk" id="000012" pri="10">
<entry>a</entry>
<rozwiniecie>minuskuła: a</rozwiniecie>
<tresc>pierwsza litera <ref target="0220101">alfabetu łacińskiego</ref> i alfabetów na nim opartych, w tym <ref target="0220152">alfabetu polskiego.</ref></tresc>
</haslo>
</slownik>

Element haslo zawiera atrybuty typ, id oraz pri. Typ określa tematykę hasła, id numer hasła w bazie danych, a pri priorytet hasła. Definicja DTD określająca taką budowę Elementu może wyglądać następująco:

<!ATTLIST haslo typ CDATA (jezyk|sport|gramatyka) "brak" #REQUIRED
id CDATA #REQUIRED
pri CDATA (1|2|3|4|5|6|7|8|9|10) "1" #REQUIRED>

Definicja określa, że hasło musi posiadać trzy atrybuty – typ, id oraz priorytet. Następnie informuje parser, że typ może przyjąć wartość jezyk, sport lub gramatyka, a domyślnie otrzymuje wartość brak. Dla ID nie ma takich ścisłych deklaracji, może to być dowolny tekst, natomiast pri (priorytet) musi zawierać się w przedziale od 1 do 10, a domyślnie otrzymuje wartość 1.

Chociaż za pomocą definicji DTD można sprawdzić zarówno poprawność samej struktury, jak również niektórych Elementów, to jest to zaledwie ułamek potęgi zastosowania Schematu XML.

Schemat XML

Schemat XML to nic innego jak dokument XML zawierający komplet informacji do sprawdzenia innego dokumentu XML. W porównaniu do DTD ma szereg zalet:

  • Schemat XML sam w sobie jest dokumentem XML. Można go zatem przetwarzać tymi samymi narzędziami, co dokumenty, które definiuje. Można na przykład wykorzystać Schemat XML do automatycznego sprawdzania wprowadzanych danych w czasie rzeczywistym przy wykorzystaniu JavaScript.

  • Schemat XML obsługuje typy danych i umożliwia szczegółowe zdefiniowanie zawartości Elementu. W przeciwieństwie do DTD, Schemat XML może informować parser, że dany Element musi składać się z określonych danych, np. musi być liczbą całkowitą lub adresem internetowym, albo że musi posiadać odpowiednią długość lub budowę.

  • Schemat XML jest rozszerzalny. Oprócz zdefiniowanych typów danych, można tworzyć własne lub dostosować te z góry zadane do indywidualnych potrzeb. Na przykład kody pocztowe mają odmienną formę zapisu w każdym kraju, można więc zdefiniować typ kodu pocztowego, który będzie się obowiązkowo składać z dwóch cyfr, półpauzy i trzech cyfr.

Przykładowy Schemat XML

Dla porównania istoty działania Schematu XML i DTD zostanie wykorzystany ten sam przykład struktury XML (ten bardziej rozbudowany):

<?xml version="1.0"?>
<slownik>
<haslo typ="jezyk" id="000012" pri="10">
<entry>a</entry>
<rozwiniecie>minuskuła: a</rozwiniecie>
<tresc>pierwsza litera <ref target="0220101">alfabetu łacińskiego</ref> i alfabetów na nim opartych, w tym <ref target="0220152">alfabetu polskiego.</ref></tresc>
</haslo>
</slownik>

Schemat XML zawierający Elementy „slownik”, „haslo” oraz „tresc” będzie znacznie bardziej skomplikowany.

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xs:element name="slownik">
<xs:complexType>
<xs:sequence>
<xs:element ref="haslo" minOccurs="1"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="haslo">
<xs:complexType>
<xs:sequence>
<xs:element ref="entry" minOccurs="1"/>
<xs:element ref="rozwiniecie" minOccurs="0"/>
<xs:element ref="tresc" minOccurs="1"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="tresc" type="xsd:string"/>
</xs:schema>

Powyższy Schemat XML nie określa niczego ponad to, co określało DTD, ale robi to w inny, bardziej przejrzysty sposób. Składnia pliku Schematu XML nie różni się od składni dokumentu XML, dzięki czemu jest bardziej czytelna (acz zauważalnie dłuższa). Dzięki temu każde oprogramowanie zdolne odczytać języki znakowane (XML, xHTML) bez trudu odczytuje pliki Schematu XML.

W przypadku bardziej złożonych warunków Schemat XML, w przeciwieństwie do DTD, jest w stanie analizować zawartość poszczególnych Elementów. Na przykład można zadeklarować, że treść hasła nie może być dłuższa niż 20 znaków:

<xs:element name="tresc">
<xs:simpleType>
<xs:restriction base="xsd:string">
<xs:maxLength value="20">
</xs:restriction>
</xs:simpleType>
</xs:element>

W ten sam sposób można ograniczać lub całkowicie wyłączać możliwość używania w poszczególnych Elementach liter, cyfr czy dowolnych innych znaków, a nawet zmusić użytkownika do wprowadzania danych w ściśle określony sposób. Idealnym przykładem jest kod pocztowy, który składa się z dwóch cyfr, półpauzy i trzech cyfr. Wystarczy wprowadzić poniższą definicję w Schemacie:

<xs:element name="kod_pocztowy">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="[0-9]{2}–[0-9]{3}?"/>
</xs:restriction>
</xs:simpleType>
</xs:element>

Element xs:pattern określa, że dany Element musi mieć budowę w postaci „cyfr sztuk dwie półpauza cyfr sztuk trzy”. Schematy XML wykorzystują tzw. wyrażenia regularne (RegExp) do wyszukiwania dowolnych ciągów znaków spełniających określone warunki.

Powyższe przykłady opisują podstawowe zasady zastosowania DTD lub Schematu XML, jak również najprostsze warianty wykorzystania jednego i drugiego. Jest to jedynie wierzchołek góry lodowej w stosunku do ogromu możliwości, jakie oferują. Ich praktyczne zastosowania są nieograniczone, np.:

  • Ograniczają możliwości popełniania błędów przez autorów i redaktorów;

  • Umożliwiają pracę z tekstem w dowolnym systemie obsługującym XML lub dowolny inny język kompatybilny z XML (np. JSON)

  • Umożliwiają automatyczne przetwarzanie tekstu wewnątrz i na zewnątrz wydawnictwa przez większość systemów informatycznych, w szczególności systemy Pay per View, bazy danych czy kompilatory treści;

  • Umożliwiają tworzenie automatycznych eksportów „w poprzek” publikacji według zadanych kryteriów.

Więcej o praktycznych zastosowaniach na podstawie przykładów opowiemy w następnej części artykułu. Na zakończenie jedna pocieszająca myśl – większość programów obsługujących XML pozwala tworzyć treść w oderwaniu od kodu. Jeśli tysiące linii tagów i wyrażenia regularne wydają się przerażające, to dobra wiadomość jest taka, że praktycznie każdą funkcję dostępną w DTD lub schemacie XML da się zamknąć w proste do zrozumienia i szybkie w obsłudze droplisty i okienka wyboru.

Ciąg dalszy nastąpi

Ciąg dalszy serii XML dla Menedżerów i Wydawców już wkrótce.  Informacje o kolejnym artykule pojawią się na naszym profilu Facebook oraz LinkedIn

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *