XML

Extensible Markup Language


Łukasz Głąb

8 listopad 2001




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


  2. 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ę.


  3. 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ń
    ? - zero lub jedno wystąpienie
    * - zero 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" ?>.

  4. 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".


  5. Definiowanie typów
    W schematach elementy i atrybuty mogą mieć określony typ: prosty lub złożony.


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

    2. 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">

  6. 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"?>

  7. 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=".&gt;0 and .&lt;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".


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


  9. Bibliografia

    1. "XML" Elizabeth Castro

    2. http://www.cookwood.com

    3. http://www.xml.com