Wprowadzenie


RELAX NG (ang. REgular LAnguage for XML Next Generation) to język schematów do języka XML. Został stworzony przez organizację OASIS i stanowi część proponowanego przez ISO/IEC standardu DSDL.
Język ten dobrze charakteryzuje następujące stwierdzenie:
90% funkcjonalności XML Schema przy 10% komplikacji.
Istnieją dwa rodzaje notacji:
  • składnia oparta o XML
  • składnia skrótowa (ang. RNG Compact Syntax - RNC)
idź do góry

Wzorzec typu tekst


Jest to najprostszy wzorzec, który pasuje do węzła tekstowego.
Wyrażenie opisujące węzeł tekstowy wygląda następująco:
 <text/>
idź do góry

Wzorzec <value>


Wzorzecy <value> odpowiada łańcuchom znaków o określonej wartości.
 <value>wartość</value>
idź do góry

Wzorzec opisujący elementy


Nazwa elementu jest zdefiniowana w atrybucie name wzorca element. Zawartość elementu jest zdefiniowana jako element potomny wzorca element.

Żeby zdefiniować element należy zastosować następującą konstrukcję:
 <element name="NAZWA_ELEMENTU">
  ...
 </element>
Inaczej niż miało to miejsce w przypadku atrybutów, nie wszystkie elementy mogą zawierać węzły tekstowe. Stąd, wzorzec węzła tekstowego nie jest domyślą zawartością elementów. Zawartość elementu musi więc zostać jawnie zdefiniowana, nawet w przypadku, gdy element jest elementem, który niczego nie zawiera.

Ponieważ wzorzec węzła tekstu pasuje do 0 lub więcej węzłów tekstowych, poprzednia definicja elementu NAZWA_ELEMENTU pasuje zarówno do elementu pustego
 <NAZWA_ELEMENTU/>
jak i do elementu NAZWA_ELEMENTU zawierającego tekst
 <NAZWA_ELEMENTU>to jest zawartość elementu</NAZWA_ELEMENTU>
Przykład:
 1<element name="rozklad">
 2  <element name="miejscowosc"><text /></element>
 3  <element name="linia">
 4    <element name="numer"><data type="int"/></element>
 5    <element name="poczatek"><text /></element>
 6    <element name="koniec"><text /></element>
 7  </element>
 8</element>

[pokaż zawartość pliku] [pobierz plik] idź do góry

Wzorzec opisujący atrybuty


Nazwa atrybutu jest zdefiniowana w atrybucie name wzorca attribute. Zawartość atrybutu jest zdefiniowana jako element potomny wzorca attribute.

Żeby zdefiniować atrybut należy zastosować następującą konstrukcję:
 <attribute name="NAZWA_ATRYBUTU">  
   ...
 </attribute>
Poniższy przykład pokazuje, w jaki sposób stosować wyżej podane definicje. Nazwa atrybutu, "id" jest zdefiniowana wewnątrz atrybutu name, natomiast zawartość, czyli tekst, jest elementem potomnym.
 <attribute name="id">  
   <text/>
 </attribute>
Przykład ten można odczytać w następujący sposób:
Atrybut o nazwie "id" o wartości typu tekstowego.
Ponieważ atrybut ma zawsze wartość, wzorzec typu tekst jest domyślnym wzorcem i jako taki może zostać pominięty w zapisie. Tym samym poprzednia definicja jest równoważna następującemu, krótszemu zapisowi:
 <attribute name="id"/>  
Przykład:
 1<element name="rozklad">
 2  <attribute name="okres"><text /></attribute>
 3  <element name="miejscowosc"><text /></element>
 4  <element name="linia">
 5    <attribute name="status" />
 6    <attribute name="typ" />
 7    <element name="numer"><data type="int"/></element>
 8    <element name="poczatek"><text /></element>
 9    <element name="koniec"><text /></element>
10  </element>
11</element>

[pokaż zawartość pliku] [pobierz plik] idź do góry

Wzorce nazwane


RELAX NG wykorzystuje wzorce nazwane w celu zapewnienia modularności i możliwości zastosowania rekurencji. Wzorce nazwane to wzorce "wielokrotnego użytku", do których można się odwoływać poprzez ich nazwę. Składania pozwalająca zdefiniować wzorzec nazwany jest następująca:
 <define name="NAZWA_ELEMENTU_NAZWANEGO">
   ...
 </define>
Przykład:
 1<define name="linia-attributes-defn">
 2  <attribute name="status" />
 3  <attribute name="typ" />
 4</define>

[pokaż zawartość pliku] [pobierz plik] idź do góry

Odwołania do wzorców nazwanych


Odwołanie się do wcześniej zdefiniowanych wzorców nazwanych jest bardzo proste. Wystarczy użyć znacznika ref, który wskaże wzorzec nazwany, do którego chcemy się odwołać.
 <ref name="NAZWA_WZORCA_NAZWANEGO"/>
Przykład:
 1<element name="rozklad">
 2  <attribute name="okres"><text /></attribute>
 3  <element name="miejscowosc"><text /></element>
 4  <element name="linia">
 5    <ref name="linia-attributes-defn" />
 6    <element name="numer"><data type="int"/></element>
 7    <element name="poczatek"><text /></element>
 8    <element name="koniec"><text /></element>
 9  </element>
10</element>

[pokaż zawartość pliku] [pobierz plik] idź do góry

Wzorzec <optional>


Wzorzec <optional> mówi, że jego zawartość jest opcjonalna. Może ale nie musi występować.

Poniższy przykład wyraża regułę, która mówi, że wystąpienie elementu A jak i B jest opcjonalne w sposób niezależny. W dokumencie XML'owym mogą pojawić się oba elementy, dowolny z nich lub żaden.
 <optional>
   <element name="A" ><text/></element>
 </optional>
 <optional>
   <element name="B"><text/></element>
 </optional>
Kolejny przykład wyraża inną regułę. Mówi on, że wystąpienie elementów A i B jest opcjonalne. Są one jedank od siebie zależne, tzn. w dokumencie XML mogą pojawić się albo oba albo żaden.
 <optional>
   <element name="A"><text/></element>
   <element name="B"><text/></element>
 </optional>
Ostatni przykład prezentuje opisuje jeszcze inną sytuację. Wg tej reguły oba elementy są opcjonalne, z tym że element A zawiera w sobie element B. Bezpośrednim skutkiem tego jest to w jaki sposób oba elementy mogą występować w dokumencie XML. W tym przypadku poprawne jest:
  • pominięcie obu elementów,
  • umieszczenie obu elementów,
  • umieszczenie elementu A
Mówiąc krótko, element B nie może występować bez elementu A.
 <optional>
   <element name="A"><text/></element>
   <optional>
     <element name="B"><text/></element>
   </optional>
 </optional>
Przykład:
 1<define name="linia-attributes-defn">
 2  <optional>
 3    <attribute name="status" />             
 4  </optional>
 5  <attribute name="typ" />
 6</define>

[pokaż zawartość pliku] [pobierz plik] idź do góry

Wzorzec <oneOrMore>


Wzorzec <oneOrMore> mówi o tym, że jego zawartość może występować jeden lub więcej razy.
Przykład:
 1<start>
 2  <element name="rozklad">
 3    <attribute name="okres"><text /></attribute>
 4    <element name="miejscowosc"><text /></element>
 5    <oneOrMore>
 6      <element name="linia">
 7        <ref name="linia-attributes-defn" />
 8        <element name="numer"><data type="int"/></element>
 9        <element name="poczatek"><text /></element>
10        <element name="koniec"><text /></element>
11      </element>
12    </oneOrMore>
13  </element>
14</start>

[pokaż zawartość pliku] [pobierz plik] idź do góry

Wzorzec <zeroOrMore>


Wzorzec <zeroOrMore> mówi o tym, że jego zawartość może występować zero lub więcej razy.
Przykład:
 1<element name="rozklad">
 2  <attribute name="okres"><text /></attribute>
 3  <element name="miejscowosc"><text /></element>
 4  <oneOrMore>
 5    <element name="linia">
 6      <ref name="linia-attributes-defn" />
 7      <element name="numer"><data type="int"/></element>
 8      <element name="poczatek"><text /></element>
 9      <zeroOrMore>
10        <element name="przystanek"><text /></element>
11      </zeroOrMore>
12      <element name="koniec"><text /></element>
13    </element>
14  </oneOrMore>
15</element>

[pokaż zawartość pliku] [pobierz plik] idź do góry

Wzorzec <choice>


Wzorzec <choice> pozwala zapisać przypadek, w którym dopuszczalne jest użycie jednego z wielu elementów. Przykład:
 1<define name="linia-attributes-defn">
 2  <optional>
 3    <attribute name="status">
 4      <choice>
 5        <value>remontowana</value>
 6        <value>nieczynna</value>
 7      </choice>
 8    </attribute>                    
 9  </optional>
10  <attribute name="typ">
11    <choice>
12      <value>tramwaj</value>
13      <value>autobus</value>
14    </choice>                  
15  </attribute>
16</define>

[pokaż zawartość pliku] [pobierz plik] idź do góry

Wzorzec <start>


Wewnątrz elementu <grammar> należy jawnie zdefiniować element główny <start>
 <grammar xmlns="http://relaxng.org/ns/structure/1.0">
   <start>
     ...
   </start>
 </grammar>
Przykład:
 1<start>
 2  <element name="rozklad">
 3    <attribute name="okres"><text /></attribute>
 4    <element name="miejscowosc"><text /></element>
 5    <oneOrMore>
 6      <ref name="linia-defn" />
 7    </oneOrMore>
 8  </element>
 9</start>

[pokaż zawartość pliku] [pobierz plik] idź do góry

Wzorzec <grammar>


W przypadku definiowania wzorców nazwanych, potrzebny jest kontener, w którym osadzone zostaną zarówno definicje wspomnianych wzorców nazwanych jak i elementu głównego.
Definicja elementu głównego i definicje innych wzorców tworzą łącznie tzw. gramatykę. Stąd też pochodzi nazwa <grammar> wymienionego wcześniej kontenera.
 <grammar xmlns="http://relaxng.org/ns/structure/1.0">
   ...
 </grammar>
Przykład:
 1<grammar 
 2  datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
 3  xmlns="http://relaxng.org/ns/structure/1.0">
 4  <start>
 5    <element name="rozklad">
 6      <attribute name="okres"><text /></attribute>
 7      <element name="miejscowosc"><text /></element>
 8      <oneOrMore>
 9        <ref name="linia-defn" />
10      </oneOrMore>
11    </element>
12  </start>
13</grammar>

[pokaż zawartość pliku] [pobierz plik] idź do góry