---
marp: true
theme: default
paginate: true
size: 16:9
style: |
section {
font-size: 24px;
}
section h1 {
color: #1a5276;
}
section h2 {
color: #2980b9;
}
section table {
font-size: 20px;
}
section small {
font-size: 18px;
}
---
# Wykład 8
## Relax NG — alternatywny język schematów
**Systemy Zarządzania Treścią**
Politechnika Poznańska
---
# Część 1
## Wprowadzenie do Relax NG
---
## Czym jest Relax NG?
> **Relax NG** (REgular LAnguage for XML Next Generation) to język schematów dla dokumentów XML, oparty na **gramatykach regularnych** — alternatywa dla DTD i XML Schema.
### Geneza i status
| Aspekt | Informacja |
|---|---|
| **Autor** | James Clark (współtwórca XSLT) |
| **Standard ISO** | ISO/IEC 19757-2 (DSDL) |
| **Standard OASIS** | RELAX NG Specification |
| **Dwie składnie** | XML (pełna) i compact (skrótowa) |
| **Podstawa teoretyczna** | Gramatyki regularne drzew |
### Filozofia projektowa
Relax NG łączy **prostotę i moc DTD** z **formalną czystością** gramatyk regularnych. W przeciwieństwie do XML Schema, model jest **jednolity i przewidywalny** — bez rozróżnienia na typy proste/złożone jako osobnych bytów.
---
## Dwie składnie Relax NG
Relax NG występuje w dwóch równoważnych formach składniowych:
### 1. Składnia XML (pełna)
```xml
```
### 2. Składnia compact (skrótowa)
```
element addressBook {
element card {
element name { text },
element email { text }
}*
}
```
> Obie składnie są **równoważne** — narzędzie Trang konwertuje między nimi automatycznie.
---
## Relax NG na tle DTD i XML Schema
| Cecha | DTD | XML Schema | Relax NG |
|---|---|---|---|
| **Podstawa** | gramatyki SGML | typy + struktury | gramatyki regularne |
| **Składnia** | własna (nie-XML) | XML | XML + compact |
| **Typy danych** | 10 typów | 44 wbudowane + własne | dowolne (przez biblioteki) |
| **Jednolitość modelu** | — | podział proste/złożone | jednolity model wzorców |
| **Przestrzenie nazw** | brak | pełne | pełne (klasy nazw) |
| **Mieszana zawartość** | ograniczona | możliwa | naturalna (mixed) |
| **Przeplot (interleave)** | brak | brak | tak |
| **Modularyzacja** | encje parametryczne | include/import/redefine | include/externalRef/combine |
| **Złożoność specyfikacji** | niska | bardzo wysoka | niska–średnia |
> Relax NG oferuje **najprostszy formalnie** model spośród trzech języków — jednolity mechanizm "wzorców" zamiast podziału na typy. Dla porównania: DTD omówione w **wykładzie 4**, XML Schema w **wykładach 5–7**.
---
## Zasada działania — wzorce
Relax NG opiera się na jednym, uniwersalnym pojęciu: **wzorca** (*pattern*).
> **Wzorzec** opisuje dopuszczalną strukturę fragmentu dokumentu — elementy, atrybuty, tekst i ich kombinacje.
### Cechy modelu wzorców
- Wszystko jest wzorcem — nie ma osobnych "typów",
- Wzorce **składają się** rekurencyjnie (pattern composition),
- Schemat to **gramatyka** złożona ze wzorców,
- Walidacja = dopasowanie dokumentu do wzorca.
### Przykład podstawowego wzorca
```xml
```
Ten wzorzec oznacza: element o nazwie `name`, zawierający dowolny tekst.
---
# Część 2
## Podstawowe wzorce
---
## Wzorce element, attribute, text, empty
Cztery podstawowe wzorce opisują fundament dokumentu XML:
| Wzorzec | Znaczenie | Przykład |
|---|---|---|
| `` | element o danej nazwie | `` |
| `` | atrybut o danej nazwie | `` |
| `` | dowolny tekst | `` |
| `` | brak treści i atrybutów | `` |
### Przykład — prosty dokument
**Dokument XML:**
```xml
John Smith
js@example.com
```
**Schemat Relax NG:**
```xml
```
---
## Odpowiednik DTD — porównanie
Ten sam dokument opisany w DTD:
```xml
]>
```
### Porównanie zapisu
| Element struktury | DTD | Relax NG |
|---|---|---|
| Element główny | `` | `` |
| Powtórzenie (0+) | `card*` | `` |
| Sekwencja | `(name, email)` | kolejne wzorce |
| Tekst | `#PCDATA` | `` |
> Relax NG jest **bardziej rozwlekły** w składni XML, ale **bardziej jednolity** — każda konstrukcja jest wzorcem.
---
## Krotność: zeroOrMore, oneOrMore, optional
Relax NG wyraża liczebność przez **wzorce-kontenery**:
| Wzorzec | Znaczenie | Odpowiednik DTD |
|---|---|---|
| `` | zero lub więcej | `*` |
| `` | jeden lub więcej | `+` |
| `` | zero lub jeden | `?` |
| *(brak kontenera)* | dokładnie raz | *(brak)* |
### Przykład — opcjonalny element
```xml
```
> `optional` oznacza, że element `note` **może**, ale nie musi wystąpić.
---
## Przestrzeń nazw Relax NG
Wszystkie elementy wzorca należą do przestrzeni nazw:
`http://relaxng.org/ns/structure/1.0`
### Dwa sposoby deklaracji
**Domyślna przestrzeń nazw:**
```xml
```
**Prefiks:**
```xml
```
> Każdy element wzorca **musi** być kwalifikowany tą przestrzenią nazw — inaczej jest traktowany jako adnotacja (ignorowany).
---
# Część 3
## Wzorce złożone
---
## Wzorzec choice — alternatywa
`choice` dopasowuje **jeden** z podanych wzorców:
```xml
```
### Odpowiednik DTD
```xml
```
### Znaczenie
- `choice` = **albo** `name`, **albo** para `givenName` + `familyName`,
- `group` = **grupowanie** (sekwencja), potrzebne, gdy alternatywa dotyczy więcej niż jednego elementu.
---
## Wzorzec group — sekwencja
`group` grupuje wzorce w **sekwencję** (wszystkie po kolei):
```xml
```
### Kiedy group jest konieczny?
`group` jest potrzebny, gdy chcemy zgrupować kilka wzorców jako **całość** — np. jako jedną gałąź `choice`.
> Bez `group` nie dałoby się wyrazić "albo pojedynczy `name`, albo para `givenName`+`familyName`" — bo `choice` przyjmuje pojedyncze wzorce.
---
## Wzorzec interleave — przeplot
`interleave` pozwala elementom potomnym występować w **dowolnej kolejności**:
```xml
```
### Semantyka interleave
Sekwencja elementów pasuje do `interleave`, jeśli jest **przeplotem** (interleavingiem) sekwencji pasujących do wzorców-dzieci.
### Przykład z HTML ``
```xml
```
> `interleave` to cecha **unikatowa** Relax NG — ani DTD, ani XML Schema nie oferują tak elastycznego mechanizmu.
---
## interleave vs łącznik `&` z SGML
`interleave` jest **silniejszy** niż łącznik `&` znany z SGML:
| Wyrażenie | Dopasuje `A A B`? | Dopasuje `A B A`? |
|---|---|---|
| `A* & B` (SGML) | ✅ tak | ❌ nie |
| `interleave(A*, B)` (Relax NG) | ✅ tak | ✅ tak |
> `interleave` pozwala na **pełne przeplatanie** sekwencji, podczas gdy `&` wymaga blokowego ułożenia.
---
## Wzorzec mixed — zawartość mieszana
`mixed` to **skrót** dla przeplatania tekstu z innymi wzorcami:
```
p ⟺ p
```
### Przykład — treść mieszana
```xml
```
> `mixed` naturalnie wyraża treść typu "tekst przeplatany elementami formatującymi" — bez ograniczeń znanych z DTD.
---
## Elementy a atrybuty — kolejność
Relax NG zachowuje **rozróżnienie** między elementami a atrybutami:
### Kolejność elementów — istotna
```xml
```
Powyższy wzorzec **nie** dopasuje `......` — elementy muszą być w zadeklarowanej kolejności.
### Kolejność atrybutów — nieistotna
Wzorzec `` dopasuje **oba** układy atrybutów (kolejność atrybutów w XML nie ma znaczenia).
> Zasada: kolejność **elementów** ma znaczenie, kolejność **atrybutów** nie — zgodnie z modelem XML.
---
## Domyślna zawartość: text vs empty
Ważna asymetria między wzorcami `element` i `attribute`:
| Wzorzec | Domyślna zawartość | Zapis skrócony |
|---|---|---|
| `` | `` | `attribute` bez treści = tekst |
| `` | **niedozwolone** | element wymaga jawnego wzorca |
### Przykład
```xml
```
> Element bez treści i atrybutów opisuje się jawnie przez ``. Wyjątek: element z samymi atrybutami nie wymaga `` — atrybuty już "wypełniają" wzorzec.
---
# Część 4
## Gramatyki i nazwane wzorce
---
## Wzorce nazwane: grammar, start, define, ref
Dla nietrywialnych schematów wygodnie jest **nazywać** części wzorca:
```xml
```
### Struktura gramatyki
| Element | Rola |
|---|---|
| `` | Kontener gramatyki — jeden `` i zero lub więcej `` |
| `` | Wzorzec początkowy (dopasowywany do całego dokumentu) |
| `` | Nazwana definicja wzorca |
| `[` | Odwołanie do nazwanej definicji |
> Gramatyka jest dopasowywana przez dopasowanie wzorca w elemencie ``.
---
## Styl zbliżony do DTD
Relax NG pozwala pisać gramatyki w stylu przypominającym DTD — każdy element jako osobna definicja:
```xml
]
```
> Ten styl jest czytelny dla osób przyzwyczajonych do DTD — każda definicja odpowiada jednemu typowi dokumentu.
---
## Odwołania rekurencyjne
Relax NG pozwala na **rekurencyjne odwołania** — pod warunkiem, że rekursja jest "przez element":
```xml
```
### Ograniczenie rekursji
Rekurencyjne odwołanie musi **przechodzić przez element**. Poniższa definicja jest **niedozwolona** (rekursja bezpośrednia bez elementu):
```xml
```
> To ograniczenie gwarantuje **rozstrzygalność** gramatyki — zapobiega nieskończonym pętlom.
---
# Część 5
## Typy danych
---
## Wzorzec data — typy danych
Relax NG odwołuje się do **zewnętrznych bibliotek typów** (np. W3C XML Schema Datatypes):
```xml
```
### Atrybuty wzorca data
| Atrybut | Rola |
|---|---|
| `type` | Nazwa typu w bibliotece |
| `datatypeLibrary` | URI identyfikujące bibliotekę typów |
### Domyślna biblioteka
Atrybut `datatypeLibrary` może być **dziedziczony** — zwykle deklaruje się go na elemencie głównym:
```xml
```
---
## Ograniczenie: data musi dopasować całość
Wzorzec `data` musi dopasować **całą zawartość** elementu lub atrybutu — nie można mieszać `data` z innymi wzorcami treści:
### Niedozwolone
```xml
```
### Dozwolone
```xml
```
> Ograniczenie to nie dotyczy wzorca `` — tylko `data` i `value` muszą dopasować całość.
---
## Parametry typów danych
Typy danych mogą mieć **parametry** przekazywane elementem ``:
```xml
127
```
### Zasada
- Parametry definiowane są przez **słownik typów** (datatyping vocabulary),
- `wartość` jako dziecko elementu `data`.
> Dzięki parametrom Relax NG może wyrazić np. "napis o maksymalnej długości 127 znaków" — podobnie jak aspekty w XML Schema.
---
## Wzorzec value — wyliczenia
`value` dopasowuje **konkretną wartość** (wyliczenie):
```xml
html
text
```
### value vs data
| Wzorzec | Znaczenie |
|---|---|
| `` | **dowolna** wartość danego typu |
| `` | **konkretna** wartość danego typu |
### Normalizacja białych znaków
Domyślnie `value` porównuje po **normalizacji białych znaków** (usunięcie skrajnych, scalenie środkowych). Aby porównywać dokładnie, użyj `type="string"`:
```xml
html
```
> `value type="string"` porównuje **bez** normalizacji — " html " nie dopasuje "html".
---
## Wzorzec list — listy wartości
`list` dopasowuje **ciąg tokenów rozdzielonych spacjami**:
```xml
```
### Warianty
**Jeden lub więcej elementów:**
```xml
```
**Parzysta liczba elementów (pary):**
```xml
```
> `list` dzieli napis na tokeny i dopasowuje je do wzorca wewnętrznego — odpowiednik `xsd:list`.
---
# Część 6
## Przestrzenie nazw i klasy nazw
---
## Przestrzenie nazw — atrybut ns
Relax NG jest **świadomy przestrzeni nazw** — nazwa elementu/atrybutu składa się z nazwy lokalnej i URI przestrzeni nazw.
```xml
```
### Dopasuje
```xml
```
### Nie dopasuje
```xml
```
---
## Dziedziczenie atrybutu ns
Atrybut `ns` jest **dziedziczony** przez elementy potomne:
```xml
```
### Różnica dla atrybutów
Atrybut `ns` **nie jest dziedziczony** przez wzorce `attribute` — domyślnie mają pustą przestrzeń nazw:
```xml
```
> To odzwierciedla fakt, że w XML atrybuty **nie dziedziczą** domyślnej przestrzeni nazw.
---
## Nazwy kwalifikowane
Zamiast atrybutu `ns` można używać **prefiksów** w wartości `name`:
```xml
```
### Zasada
Prefiks w `name` **określa przestrzeń nazw** niezależnie od atrybutu `ns`. Domyślna przestrzeń nazw (xmlns) **nie** wpływa na dopasowywanie nazw we wzorcach.
---
## Klasy nazw (name classes)
Klasa nazw pozwala dopasować **wiele nazw** naraz. Podstawowe klasy:
| Klasa | Znaczenie |
|---|---|
| `` | dowolna nazwa (lokalna + przestrzeń) |
| `` | dowolna nazwa w danej przestrzeni nazw |
| `` | konkretna nazwa |
| `` | suma klas |
| `` | wykluczenie z klasy |
### Przykład — dowolny dokument XML
```xml
```
---
## Klasy nazw — except i nsName
```xml
```
### Znaczenie
Powyższy wzorzec pozwala elementowi `card` na **dowolną liczbę atrybutów** kwalifikowanych przestrzenią nazw **inną** niż przestrzeń `card` — ale nie z przestrzeni `card` ani bez przestrzeni.
### Zastosowanie klas nazw
Klasy nazw umożliwiają **otwartą walidację** (*lax validation*) — pozwalają na "dowolne atrybuty z wyjątkiem tych, które definiujemy ściśle".
---
## Lax validation — przykład z xml:space
Problem: chcemy pozwolić na **dowolne atrybuty**, ale jeśli wystąpi `xml:space`, to musi mieć wartość `default` lub `preserve`.
### Rozwiązanie z except
```xml
xml:space
default
preserve
```
> Klasa `anyName` z `except` pozwala wykluczyć `xml:space` z "dowolności", a następnie zdefiniować go **ściśle** osobno.
---
# Część 7
## Modularyzacja
---
## Odwołania zewnętrzne — externalRef
`externalRef` odwołuje się do wzorca zdefiniowanego w **osobnym pliku**:
```xml
```
### Łączenie wzorców z plików
```xml
```
> `externalRef` to prosty mechanizm **wielokrotnego użycia** schematów z osobnych plików.
---
## Łączenie definicji — combine
Wiele definicji o tej samej nazwie łączy się atrybutem `combine`:
```xml
```
Jest to równoważne:
```xml
```
### Wartości combine
| Wartość | Znaczenie |
|---|---|
| `choice` | suma alternatyw (elementy) |
| `interleave` | przeplot (zwykle dla atrybutów) |
---
## combine="interleave" dla atrybutów
Przy łączeniu atrybutów typowo używa się `interleave`:
```xml
```
Jest to równoważne (dla atrybutów kolejność nie ma znaczenia):
```xml
```
> Zasada: `combine="choice"` dla elementów, `combine="interleave"` dla atrybutów.
---
## Scalanie gramatyk — include
`include` scala gramatyki z osobnych plików:
```xml
```
### Działanie
- Definicje z `inline.rng` są **dołączane** do gramatyki,
- `combine="choice"` **rozszerza** definicję `inline.class` o nowe elementy.
---
## notAllowed — wzorzec "nic"
`notAllowed` **nigdy nic nie dopasowuje** — używany do budowy punktów rozszerzeń:
```xml
```
### Zastosowanie
`inline.extra` jest domyślnie "pusty" (nic nie dopasowuje), ale gramatyka dołączająca może go **rozszerzyć** przez `combine="choice"`:
```xml
```
> `notAllowed` pełni rolę **wtyczki rozszerzeń** — jak punkt zaczepienia dla przyszłych modyfikacji.
---
## Zastępowanie definicji — include z define
Element `include` może zawierać `define`, które **zastępują** definicje z dołączanej gramatyki:
```xml
```
### Zasada
- Definicja `cardContent` w `include` **zastępuje** oryginalną,
- Analogicznie `start` wewnątrz `include` zastępuje `start` dołączanej gramatyki.
---
## Gramatyki zagnieżdżone — parentRef
Relax NG pozwala **zagnieżdżać gramatyki**. `parentRef` ucieka z bieżącej gramatyki do definicji gramatyki **nadrzędnej**:
```xml
```
### Znaczenie
Wzorzec `table.rng` (zagnieżdżona gramatyka) redefiniuje `cell.content`, odwołując się do `inline` z gramatyki **zewnętrznej** — to umożliwia **parametryzację** dołączanych modułów.
---
## Adnotacje
Elementy i atrybuty z **innej przestrzeni nazw** niż Relax NG są **ignorowane** — można ich używać jako adnotacji:
```xml
Informacja o karcie.
```
### Element div
`div` grupuje definicje (np. w moduły) i przenosi adnotacje:
```xml
...
...
...
```
---
## Podsumowanie
| Temat | Kluczowe wnioski |
|---|---|
| **Relax NG** | Język schematów oparty na gramatykach regularnych (ISO 19757-2) |
| **Dwie składnie** | XML (pełna) i compact (skrótowa) |
| **Wzorce** | element, attribute, text, empty, group, choice, optional, zeroOrMore, oneOrMore |
| **interleave/mixed** | Unikatowy mechanizm przeplotu — brak odpowiednika w DTD/XSD |
| **Gramatyki** | grammar, start, define, ref — nazwane wzorce i rekursja |
| **Typy danych** | data (typy zewnętrzne), value (wyliczenia), list (listy) |
| **Przestrzenie nazw** | ns, klasy nazw: anyName, nsName, except |
| **Modularyzacja** | externalRef, combine, include, notAllowed, parentRef |
### Porównanie trzech języków
| | DTD | XML Schema | Relax NG |
|---|---|---|---|
| **Prostota** | wysoka | niska | średnia |
| **Siła wyrazu** | niska | wysoka | wysoka |
| **Jednolitość** | — | podział typów | jednolite wzorce |
| **Przeplot** | brak | brak | tak |
---
# Dziękuję za uwagę
**Systemy Zarządzania Treścią**
Politechnika Poznańska