XML
Extensible Markup Language
Łukasz Głąb
8 listopad 2001
Wstęp
Stale rosnąca popularność
stron webowych oraz zwiększająca się liczba ich zastosowań stwarza
zapotrzebowanie na nowe technologie, mogące sprostać coraz większym
wymaganiom. Ekspansję Internetu bardzo ułatwiła prostota HTML-a.
Jednak ta prostota narzuca także ograniczenia, gdy trzeba obsłużyć
ogromną i stale rosnącą ilość informacji. XML to rozszerzalny język
znaczników wywodzący się z tej samej technologii co HTML.
Pozwala jednak na lepsze obsłużenie informacji – przede wszystkim
przez umożliwienie wprowadzenia logicznej struktury dokumentu.
Dokumenty XML
Sposób tworzenia
dokumentów XML różni się od tworzenia stron w HTML.
Przede wszystkim XML jest bardziej restrykcyjny jeśli chodzi o
składnię – znaczniki muszą być zamykane, wymagane jest użycie
cudzysłowów przy nadawaniu wartości atrybutom znaczników,
wymagane jest przestrzeganie wielkości liter oraz inne drobiazgi.
Ograniczenia te utrudniają pisanie kodu w XML-u, ale jednocześnie
ułatwiają pracę parserom przez co strona może być szybciej
wyświetlona.
Przykład 1
<?xml version="1.0" encoding="iso-8859-2"?> <zagrożone_gatunki> <zwierzę> <nazwa język="polski">Tygrys</nazwa> <nazwa język="łacina">Panthera tigris</nazwa> <zagrożenia> <zagrożenie>kłusownictwo</zagrożenie> <zagrożenie>dewastacja środowiska</zagrożenie> <zagrożenie>handel tygrysimi kośćmi stosowanymi w tradycyjnej medycynie chińskiej</zagrożenie> </zagrożenia> </zwierzę> ... </zagrożone_gatunki>
Otwarcie takiego dokumentu (zapisanego z rozszerzeniem .xml) w przeglądarce spowoduje wyświetlenie jego zawartości w postaci hierarchicznej (ustalone wcięcia, kolory znaczników) oraz przed znacznikami zawierającymi inne znaczniki pojawi się znak "-". Kliknięcie na takim znaku spowoduje jego zamianę na "+" i zwinięcie zawartości znacznika – nie jest to zwyczajne wyświetlenie źródła dokumentu na ekran: po sparsowaniu go przeglądarka prezentuje jego logiczną strukturę.
DTD
Z Przykładu 1 znaczniki
nie są w żaden sposób zdefiniowane. Jest to dopuszczalne, ale
jeśli stosujemy automatyczne generowanie kodu (np. gdy zawartością
strony ma być wynik jakiejś wyszukiwarki albo dajemy użytkownikowi
możliwość wstawiania lub kasowania wyświetlanych danych), to
powinniśmy móc zagwarantować spójność danych. Można to
uzyskać przez stosowanie schematów. Są dwa podstawowe sposoby
pisania schematów: DTD i XML Schema.
DTD ma postać:
<!DOCTYPE nazwa_elementu_głównego [ definicje elementów i ich atrybutów ]>
gdzie nazwa_elementu_głównego to nazwa znacznika najbardziej zewnętrznego w stosunku do definiowanych elementów (w Przykładzie 1 będzie nim element zagrożone_gatunki). DTD może być zdefiniowane w dokumencie XML lub na zewnątrz – musi mieć wtedy rozszerzenie .dtd .
Definicja elementu:
<!ELEMENT nazwa_elementu opis_zawartości_znacznika>
gdzie opis_zawartości_znacznika określa jakie inne znaczniki mogą się zawierać w znaczniku o nazwie nazwa_elementu albo wskazuje, że może się tam znajdować dowolny tekst lub nic, np.
Przykład 2
<!ELEMENT zwierzę (nazwa+ zagrożenia? występowanie*)>+ - jedno lub więcej wystąpień
Przykład 3
<!ELEMENT zagrożenie (#PCDATA)>#PCDATA oznacza dowolne znaki.
Przykład 4
<!ELEMENT obrazek EMPTY>EMPTY określa, że znacznik "obrazek" nie obejmuje żadnej treści.
Definicja atrybutu:
<!ATTLIST nazwa_elementu nazwa_atrybutu opis_wartości_atrybutu dodatkowe_wymagania>
gdzie opis_wartości_atrybutu jest listą dopuszczalnych wartości (wartość1 | wartość2) lub określeniem dowolnych znaków (CDATA "2001" – wartością atrybutu jest ciąg dowolnych znaków; atrybut ma wartość domyślną "2001"). Dodatkowe wymagania określają czy dany atrybut jest wymagany (#REQUIRED), ma ustaloną wartość (#FIXED "wartość"), ciąg dowolnych znaków nie ma wartości domyślnej (#IMPLIED), np.
Przykład 5
<!ATTLIST nazwa język (polski | łacina) #REQUIRED>Element "nazwa" ma wymagany atrybut "język".
Przykład 6
<!ATTLIST obrazek plik CDATA "c:\www\pic.jpg" x CDATA #REQUIRED y CDATA #REQUIRED autor CDATA #IMPLIED>Element "obrazek" ma atrybuty: "plik", "x", "y" i "autor".
Definiowanie DTD często może być uproszczone przez stosowanie encji. Encja to pewien zbiór opisów elementów i atrybutów lub fragment treści dokumentu XML.
Przykład 7
<!ENTITY % opis_obrazka SYSTEM "obrazek.dtd">
Po takiej definicji wystarczy w DTD umieścić napis "%opis_obrazka;", by móc dołączyć DTD z opisem obrazka.
Niech plik "dewastacja_opis.ent"
zawiera następującą treść:
<dewastacja>Dewastacja środowiska przyczynia się do zagłady wielu zagrożonych gatunków zwierząt</dewastacja>
Wtedy zapis:
<!ENTITY opis_dewastacji SYSTEM "dewastacja_opis.ent">umożliwia wklejenie do treści dokumentu zawartości pliku "dewastacja_opis.ent" przez wpisanie &opis_dewastacji; – na początku dokumentu musi być <?xml standalone="no" ?>.
XML Schema
DTD jest proste w użyciu,
ale ma pewne ograniczenia – wszystkie deklaracje są globalne, co
znaczy, że nie można definiować dwóch różnych elementów
o takiej samej nazwie, nawet jeśli zawsze występują w różnym
kontekście. Poza tym DTD nie jest w stanie sprawdzić, jakiego typu
informacje może zawierać element lub atrybut. XML Schema umożliwia
znacznie dokładniejsze określenie dokumentu XML.
Schemat, zapisywany w pliku z rozszerzeniem .xsd, ma postać:
<?xml version="1.0"?> <xsd:schema xmlns:xsd="http://www.w3.org/2000/10/XMLSchema"> ... </xsd:schema>
Wszystkie elementy i typy zaczynające się od xsd: będą traktowane jako pochodzące z tak zdefiniowanej przestrzeni nazw. W schemacie określa się elementy i atrybuty oraz ich typy.
Przykład 8
Użycie schematów:
<zagrożone_gatunki xmlns="URL do pliku ze schematem 1" xmlns:rzeki="URL do pliku ze schematem 2"> <zwierzę> <nazwa język="polski">Wydra amazońska</nazwa> <rzeki:nazwa>Amazonka</rzeki:nazwa>
Schemat 1 nie jest prefiksowany, więc jest to schemat domyślny – określa elementy: "zagrożone_gatunki", "zwierzę" i "nazwa", a schemat 2 ma prefiks "rzeki", więc określa wszystkie elementy postaci "rzeki:nazwa_elementu".
Definiowanie typów
W schematach elementy i atrybuty mogą
mieć określony typ: prosty lub złożony.
Typy proste
Przykład 9
<xsd:element name="populacja" type="xsd:integer">
Przykład 10
<xsd:simpleType name="kodPocztowy"> <xsd:restriction base="xsd:string"> <xsd:pattern value="\d{2}(-\d{3})?"/> </xsd:restriction> </xsd:simpleType> <xsd:element name="zipcode" type="kodPocztowy">
"xsd:restriction" umożliwia ograniczenie typu bazowego, a "xsd:extension" – rozszerzenie (np. przez dodanie atrybutu).
Poprawne elementy:
<zipcode>02</zipcode> <zipcode>02-495</zipcode>
Typy złożone
Przykład 11
<xsd:complexType name="zwierzęTyp"> <xsd:sequence> <xsd:element name="zagrożenia" type="zagrożeniaTyp" minOccurs="2"/> <xsd:element name="waga" type="xsd:string" maxOccurs="3"/> <xsd:element name="długość" type="xsd:integer"/> <xsd:attribute name="narodziny" type="xsd:date"> </xsd:sequence> </xsd:complexType>
"minOccurs" i "maxOccurs" określają odpowiednio minimalną i maksymalną liczbę wystąpień danego elementu. "xsd:sequence" wymusza ustaloną kolejność elementów zawartych w typie złożonym. Może tu wystąpić również "xsd:choice" dające wybór jednego lub grupy elementów, "xsd:all" – wystąpienie elementów w dowolnej kolejności. Dopuszczalne jest także definiowanie grup elementów i grup atrybutów, których można później używać w definicjach różnych typów.
Przykład 12
Grupa elementów:
<xsd:group name="cechy_fizyczne"> ... </xsd:group>Grupa atrybutów:
<xsd:attributeGroup name="atrybuty_zwierząt"> ... </xsd:attributeGroup>Użycie w typie złożonym:
<xsd:group ref="cechy_fizyczne"> <xsd:attributeGroup ref="atrybuty_zwierząt">
Kaskadowe arkusze stylów
W HTML-u każdy znacznik
ma przypisane jakieś formatowanie, które można modyfikować. W
XML-u znaczniki nie mają żadnego domyślnego formatowania. Można to
zrobić za pomocą kaskadowych arkuszy stylów (CSS).
Przykład 13
zagrożenie {display:block; position:absolute; left:9px; border:medium double red} populacja {display:inline; position:relative; left:125px}{display:block} oznacza rezerwację całego wiersza dla elementu "zagrożenie" – po wystąpieniu tego elementu jest dostawiany znak końca linii.
{display:inline} oznacza, że za
elementem "populacja" (w tym samym wierszu) może wystąpić inny
element.
Znaczenie pozostałych własności jest
intuicyjne.
Arkusz stylów zapisuje się w pliku z rozszerzeniem .css, a odwołanie do niego w dokumencie XML ma postać:
<?xml-stylesheet type="text/css" href="arkusz.css"?>
XSLT
Innym sposobem przetwarzania dokumentów XML i dającym większe
możliwości niż CSS jest przekształcanie XML za pomocą XSLT. Wynikiem
takiego przekształcenia może być inny plik XML lub plik HTML.
Procesor XSLT na podstawie pliku XML buduje drzewo – węzłami są
hierarchicznie ułożone elementy, atrybuty, wartości atrybutów
i zawartość elementów. XSLT wywołuje reguły dla wszystkich
węzłów. Reguła składa się z dwóch części: szablonu,
który określa jakich węzłów dotyczy dana reguła, oraz
instrukcji, które opisują przekształcanie węzła. Procesor
automatycznie wyszukuje reguły węzła głównego, następnie
stosuje je do głównego węzła dokumentu XML (węzła
zawierającego element główny). Reguła węzła głównego
zwykle zawiera zestaw literałów opisujących dokładnie dane
wyjściowe oraz instrukcje XSLT, które dodają coś do wyniku lub
nakazują dalsze przetwarzanie kolejnych węzłów dokumentu
źródłowego.
Przykład 14
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="/"> <html><head><title>Zagrożone gatunki</title></head> <body bgcolor="white"> <xsl:apply-templates select="zagrożone_gatunki/zwierzę"/> </body>< /html> </xsl:template>
Powyższy przykład przekształca element "zagrożone_gatunki" i wywołuje reguły dla elementu "zwierzę".
Do wyniku można dodawać zawartość konkretnych elementów z atrybutami:
<xsl:value-ofselect="zagrożone_gatunki/zwierzę/nazwa[@język='polski']"/>
Spowoduje to, że w wyniku pojawi się
zawartość elementu "nazwa" z atrybutem "język=polski".
Istnieje również alternatywny do
"apply-templates" sposób przetwarzania węzłów:
<xsl:for-each select="podgatunki"> ... </xsl:for-each>
Przetwarzane są w ten sposób wszystkie "podgatunki", ale instrukcje formatujące znajdują się pomiędzy <xsl:for-each> a </xsl:for-each>, a nie w regule "podgatunków".
Możliwe jest także warunkowe przetwarzanie:
<xsl:value-of select="."/> <xsl:iftest=".=0"> ... </xsl:if>
lub
<xsl:value-of select="."/> <xsl:choose> <xsl:when test=".=0"> ... </xsl:when> <xsl:when test=".>0 and .<50"> ... </xsl:when> ... <xsl:otherwise> ... </xsl:otherwise> </xsl:choose>
Przetwarzanie jest uzależnione od wartości zwróconej przez "xsl:value-of".
Można również posortować przetwarzane węzły:
<xsl:sort select="populacja/@rok" data-type="number"/>
Domyślnie jest sortowanie rosnące – efekt odwrotny można uzyskać dzięki atrybutowi: order="descending".
Podsumowanie
Technologia XML jest nowoczesnym rozwiązaniem dla profesjonalnej prezentacji
danych. Rozszerzalność znaczników, możliwość łączenia z
rozpowszechnionym już HTML-em, kaskadowymi arkuszami stylów,
różnorodność mechanizmów oraz różnego rodzaju
generatory kodu HTML (np. Saxon) sprawiają, że XML jest językiem
bardzo elastycznym i dającym wiele możliwości. Wiele elementów
XML jest jeszcze na etapie opracowywania standardów (np.
XSL-FO, który jest częścią składową XSL). Część przyjętych
rozwiązań i mechanizmów nie jest jeszcze zaimplementowana w
żadnej przeglądarce (np. XLink i XPointer). Pomimo tych niedogodności
(zapewne tymczasowych) XML ujawnia swoją siłę w dużych tekstowych
bazach danych udostępnianych w sieci Web.
Bibliografia
"XML" Elizabeth Castro
http://www.cookwood.com
http://www.xml.com