XML sémanyelvek

Jeszenszky, Péter

Új Széchenyi Terv logó.

A tananyag a TÁMOP-4.1.2-08/1/A-2009-0046 számú Kelet-magyarországi Informatika Tananyag Tárház projekt keretében készült. A tananyagfejlesztés az Európai Unió támogatásával és az Európai Szociális Alap társfinanszírozásával valósult meg.

A Kelet-magyarországi Informatika Tananyag Tárház logója.

Magyarország megújul logó.

Nemzeti Fejlesztési Ügynökség http://ujszechenyiterv.gov.hu/ 06 40 638-638

Az EU logója.

2010


Tartalom

Előszó
I. W3C XML Schema
Bevezetés
1. Alapfogalmak
Bevezetés
Sémák és sémadokumentumok
Sémakomponensek
Sémák ábrázolása sémadokumentumokban
Típusrendszer
Típusdefiníciók
Egyszerű és komplex típusok
Típushierarchia
2. Egyszerű típusok (adattípusok) fogalmai
Bevezetés
Adattípusok fajtái
Primitív és származtatott adattípusok
Beépített és felhasználói származtatott adattípusok
Atomi, lista és unió adattípusok
Adattípus fogalma
Értéktér
Lexikális tér
Adattípus-tulajdonságok
Adattípus-alaptulajdonságok
bounded
cardinality
numeric
ordered
Példa: a decimal adattípus
3. Egyszerű típusok (adattípusok) használata és származtatása
Bevezetés
Beépített adattípusok
Literálok használata a példányokban
Whitespace karakterek kezelése
Adattípusok definiálása
Adattípusok származtatása megszorítással
Adattípusok származtatása listaképzéssel
Adattípusok származtatása unióképzéssel
Származtatás korlátozása
Az anySimpleType adattípus
4. Komplex típusok
Bevezetés
Komplex típusok definiálása
Csak elemeket tartalmazó elemek
Tartalommodellek
Modellcsoportok
Modellcsoportokra vonatkozó korlátozások
Modellcsoportok kombinálása
Modellcsoport-definíciók
Vegyes tartalmú elemek
Tulajdonságok használata
Szövegtartalmú elemek tulajdonságokkal
Üreselemek
Komplex típusok megszorítása és kiterjesztése
Komplex típus definíciójának kiterjesztése
Komplex típus definíciójának megszorítása
Származtatás korlátozása
Polimorfizmus
Absztrakt típusok
Az anyType típus
Helyettesítők
Feladatok
5. Azonossági megszorítások
Bevezetés
Azonossági megszorítások definiálása
XPath elérési útvonalak
Szemantika
key
keyref
unique
Példák
Feladatok
6. Névterek
Bevezetés
Névterek használata
7. További lehetőségek
Bevezetés
Hiányzó értékek
Kommentárok
8. Példányok
Bevezetés
xsi:type
xsi:nil
9. Esettanulmány
Bevezetés
Programozási nyelv szintaxisának leírása XML sémával
XML szintaxisú programozási nyelvek
Egy játék programozási nyelv
XML séma
A programok végrehajtása
Feladatok
A. Beépített adattípusok
Beépített adattípusok azonosítása
Beépített primitív adattípusok
anyURI
base64Binary
boolean
date
dateTime
decimal
double
duration
float
gDay
gMonth
gMonthDay
gYear
gYearMonth
hexBinary
NOTATION
QName
string
time
Beépített származtatott adattípusok
A decimal típusból származtatott beépített adattípusok
A string típusból származtatott beépített adattípusok
B. Korlátozó adattípus-tulajdonságok
enumeration
fractionDigits
length, minLength, maxLength
length
maxLength
minLength
minExclusive, minInclusive, maxInclusive, maxExclusive
maxInclusive
maxExclusive
minExclusive
minInclusive
pattern
totalDigits
whiteSpace
C. Dokumentumok az Esettanulmány című fejezethez
XML séma
XSLT stíluslap
D. Sémadokumentumok manipulálása
Ajánlott szoftverek
<oXygen/> XML Editor
XMLSpy
Az <oXygen/> használata sémadokumentumokhoz
Sémadokumentumok megnyitása
Sémadokumentumok létrehozása
Sémadokumentumok szerkesztése
Dokumentáció előállítása
Dokumentumok érvényesítése
Irodalomjegyzék

Az ábrák listája

1.1. Típushierarchia
4.1. Irányított gráf
4.2. Példa irányított gráfra
A.1. A decimal típusból (megszorítással) származtatott adattípusok
A.2. A string adattípusból származtatott beépített adattípusok. Az éleknél a folytonos vonal megszorítással történő származtatást, a szaggatott vonal pedig lista képzésével történő származtatást jelent.
D.1. Új dokumentum létrehozása az <oXygen/>-ben
D.2. Séma diagram megjelenítése az <oXygen/>-ben
D.3. Dokumentáció előállítása az <oXygen/>-ben
D.4. Az <oXygen/> által előállított sémadokumentáció HTML-ben

A táblázatok listája

A.1. A decimal típusból (megszorítással) származtatott adattípusok értéktere

A példák listája

2.1. A decimal adattípus
3.1. Elem normalizált értéke
3.2. Elem normalizált értéke
3.3. Adattípus felső szintű definíciója és felhasználása
3.4. Névtelen adattípus definíciója és felhasználása
3.5. Adattípus származtatása megszorítással
3.6. Adattípus származtatása megszorítással
3.7. Adattípus származtatása megszorítással
3.8. Egyszerű típus definíciója
3.9. Korlátozó adattípus-tulajdonság nem megengedett alkalmazása
3.10. Lista adattípus definíciója
3.11. A string adattípus, mint elemtípus
3.12. Unió adattípus definíciója
3.13. Unió adattípus definíciója
3.14. Unió adattípus definíciója
3.15. Tag-típusdefiníciók sorrendje unió adattípus definíciójában
3.16. Származtatás korlátozása
3.17. Korlátozó adattípus-tulajdonság értékének rögzítése
4.1. Nevesített komplex típus definíciója és felhasználása
4.2. Névtelen komplex típus definíciója és felhasználása
4.3. Tartalommodell kifejezése DTD-ben és sémában
4.4. A sequence modellcsoport használata
4.5. A sequence modellcsoport használata
4.6. A choice modellcsoport használata
4.7. A choice modellcsoport használata
4.8. A choice modellcsoport használata
4.9. Az all modellcsoport használata
4.10. Nem megengedett modellcsoport
4.11. Nem egyértelmű modellcsoport
4.12. Modellcsoport-definíció
4.13. Modellcsoport-definíció
4.14. Vegyes tartalmú elem deklarálása DTD-ben
4.15. Vegyes tartalom használata
4.16. Vegyes tartalom használata
4.17. Tulajdonságok használata
4.18. Tulajdonsággal rendelkező szövegtartalmú elem használata
4.19. Tulajdonsággal rendelkező szövegtartalmú elem használata
4.20. Üreselem deklarálása
4.21. Üreselem deklarálása
4.22. Komplex típus kiterjesztése
4.23. Komplex típus kiterjesztése
4.24. Komplex típus megszorítása
4.25. Komplex típus megszorítása
4.26. Polimorfizmus
4.27. Absztrakt típus használata
4.28. Az anyType típus használata
4.29. Elemhelyettesítő használata
4.30. Tulajdonság-helyettesítő használata
5.1. A key azonossági megszorítás
5.2. A key azonossági megszorítás
5.3. A key azonossági megszorítás
5.4. A key és keyref azonossági megszorítás
5.5. A key és keyref azonossági megszorítás
5.6. A unique azonossági megszorítás
5.7.
6.1. Tennivalók leírásához készített séma névtér használata nélkül
6.2. Tennivalók leírásához készített séma cél-névtérrel (1. változat)
6.3. Tennivalók leírásához készített séma cél-névtérrel (2. változat)
6.4. Tennivalók leírásához készített séma cél-névtérrel (3. változat)
7.1. Hiányzó érték kifejezése elem hiányával
7.2. Hiányzó érték kifejezése az xsi:nil tulajdonsággal
7.3. A documentation elem használata
7.4. Az appinfo elem használata
9.1. Egy program XML-ben
B.1. Az enumeration korlátozó adattípus-tulajdonság alkalmazása
B.2. Az enumeration korlátozó adattípus-tulajdonság alkalmazása
B.3. A fractionDigits korlátozó adattípus-tulajdonság alkalmazása
B.4. A length korlátozó adattípus-tulajdonság alkalmazása
B.5. A length korlátozó adattípus-tulajdonság alkalmazása
B.6. A maxLength korlátozó adattípus-tulajdonság alkalmazása
B.7. A minLength korlátozó adattípus-tulajdonság alkalmazása
B.8. A maxExclusive korlátozó adattípus-tulajdonság alkalmazása
B.9. A minExclusive korlátozó adattípus-tulajdonság alkalmazása
B.10. A minInclusive korlátozó adattípus-tulajdonság alkalmazása
B.11. A pattern korlátozó adattípus-tulajdonság alkalmazása
B.12. A pattern korlátozó adattípus-tulajdonság alkalmazása
B.13. A totalDigits korlátozó adattípus-tulajdonság alkalmazása
C.1. Az XSLT stíluslap által előállított ANSI C program

Előszó

Az XML sémanyelvek XML dokumentumok szerkezetére és tartalmára vonatkozó megszorítások kifejezését teszik lehetővé sémák formájában. Egy XML dokumentumot érvényesnek nevezünk egy sémának megfelelően, ha szerkezete és tartalma megfelel a séma által megfogalmazott megszorításoknak. Az érvényesség ellenőrzésének folyamatát érvényesítésnek, az érvényesség ellenőrzésére képes szoftvereszközöket pedig érvényesítőknek nevezzük.

Az [XML 1.0] specifikáció részeként definiált jelölődeklarációk egy XML sémanyelvet alkotnak, az ezekből felépülő dokumentumtípus definíciók (DTD-k) pedig sémák. A DTD által biztosított lehetőségek nem felelnek meg napjaink XML feldolgozó alkalmazásai által támasztott igényeknek, amelyek fogyatékosságai például az alábbiak:

  • Nem XML szintaxis, amely nem teszi lehetővé olyan általános célú XML feldolgozó eszközök használatát, mint például az XML elemzők vagy XSLT stíluslapok.

  • Nem támogatott az XML névterek használata, amelyek megkerülhetetlenek a modern XML alkalmazásokban.

  • Nincs támogatás az SQL-ben és programozási nyelvekben tipikusan rendelkezésre álló adattípusok használatához.

  • Nincs lehetőség az elemek környezetfüggő deklarálására (minden elem csak egyszer deklarálható).

A DTD fogyatékosságai alternatív megoldások kidolgozását ösztönözték, amelynek eredményeként számos XML sémanyelv született. Napjainkban is élő és elterjedten használt sémanyelvek a W3C XML Schema, RELAX NG és Schematron. Míg az első W3C ajánlás, az utóbbi kettő ISO szabványként is létezik.

A legszélesebb körben felhasznált és támogatott sémanyelv egyértelműen a W3C XML Schema, így a könyv célja ennek bemutatása. Megjegyezzük, hogy a meglehetősen bonyolult W3C XML Schema egy egyszerűbb alternatíváját kínálja a RELAX NG sémanyelv. Az előző kettőtől gyökeresen eltérő megközelítést alkalmaz a szabályalapú Schematron sémanyelv, amely használható más sémanyelvekkel együtt is, azok hiányosságainak kiküszöbölésére.

A W3C XML Schema teljesen részletes tárgyalása meghaladja a kötet terjedelmi korlátait. A szerző elsődleges célja az volt, hogy az olvasó a lehető leghamarabb elsajátíthassa a sémanyelv gyakorlati használatát. Így a könyv elsősorban a lehetőségek szemléletes példákon keresztül történő bemutatására koncentrál. A szabvány beépített adattípusai kapcsán referenciaként is forgatható.

I. rész - W3C XML Schema

Tartalom

Bevezetés
1. Alapfogalmak
Bevezetés
Sémák és sémadokumentumok
Sémakomponensek
Sémák ábrázolása sémadokumentumokban
Típusrendszer
Típusdefiníciók
Egyszerű és komplex típusok
Típushierarchia
2. Egyszerű típusok (adattípusok) fogalmai
Bevezetés
Adattípusok fajtái
Primitív és származtatott adattípusok
Beépített és felhasználói származtatott adattípusok
Atomi, lista és unió adattípusok
Adattípus fogalma
Értéktér
Lexikális tér
Adattípus-tulajdonságok
Adattípus-alaptulajdonságok
bounded
cardinality
numeric
ordered
Példa: a decimal adattípus
3. Egyszerű típusok (adattípusok) használata és származtatása
Bevezetés
Beépített adattípusok
Literálok használata a példányokban
Whitespace karakterek kezelése
Adattípusok definiálása
Adattípusok származtatása megszorítással
Adattípusok származtatása listaképzéssel
Adattípusok származtatása unióképzéssel
Származtatás korlátozása
Az anySimpleType adattípus
4. Komplex típusok
Bevezetés
Komplex típusok definiálása
Csak elemeket tartalmazó elemek
Tartalommodellek
Modellcsoportok
Modellcsoportokra vonatkozó korlátozások
Modellcsoportok kombinálása
Modellcsoport-definíciók
Vegyes tartalmú elemek
Tulajdonságok használata
Szövegtartalmú elemek tulajdonságokkal
Üreselemek
Komplex típusok megszorítása és kiterjesztése
Komplex típus definíciójának kiterjesztése
Komplex típus definíciójának megszorítása
Származtatás korlátozása
Polimorfizmus
Absztrakt típusok
Az anyType típus
Helyettesítők
Feladatok
5. Azonossági megszorítások
Bevezetés
Azonossági megszorítások definiálása
XPath elérési útvonalak
Szemantika
key
keyref
unique
Példák
Feladatok
6. Névterek
Bevezetés
Névterek használata
7. További lehetőségek
Bevezetés
Hiányzó értékek
Kommentárok
8. Példányok
Bevezetés
xsi:type
xsi:nil
9. Esettanulmány
Bevezetés
Programozási nyelv szintaxisának leírása XML sémával
XML szintaxisú programozási nyelvek
Egy játék programozási nyelv
XML séma
A programok végrehajtása
Feladatok

Bevezetés

A W3C XML Schema a W3C által kidolgozott sémanyelv, amely ajánlásként 2001-ben került elfogadásra, és amelyet a [XML Schema: Primer], [XML Schema: Structures] és [XML Schema: Datatypes] specifikációk tárgyalnak. [XML Schema: Primer] egy a jelen könyvhöz hasonló, a lehetőségeket példákon keresztül áttekintő bevezező. [XML Schema: Structures] tárgyalja részletesen a sémanyelvet. A sémanyelv egy olyan adattípus-rendszert biztosít, amelyet akár a szabvány többi részétől függetlenül is használhatnak alkalmazások, az adattípusok tárgyalása ezért külön történik a [XML Schema: Datatypes] dokumentumban.

Míg [XML Schema: Primer] egy akár tankönyvként is használható bevezető, [XML Schema: Structures] különösen nehéz olvasmány, amelynek megértése meghaladja az átlagolvasó képességeit, hiszen ennek célközönségét az implementációkészítők jelentik, akik számára elengedhetetlen a matematikai pontosság.

Mivel vannak más XML séma nyelvek is, az egyértelműség végett használják a sémanyelvre a nem hivatalos XSD és WXS elnevezéseket is, azonban a jelenlegi szabványt felváltani hivatott 1.1 verzió már hivatalosan is az XSD nevet viseli.

A sémanyelv legfontosabb jellemzőit az alábbiakban lehet összefoglalni:

  • XML szintaxis használata

  • Önleíró (létezik a sémákhoz séma)

  • Primitív adattípusok biztosítása

  • Felhasználói típusok létrehozását támogató típusrendszer

  • XML névterek támogatása

  • Alkalmazások széles köre által használható

Hátrányként szokták felhozni a szabvány korábban már említett nehezen érthetőségét és a bonyolult, kényelmetlen szintaxist.

Jelenleg is fejlesztés alatt áll a szabvány munkatervként létező következő, 1.1 számú verziója, amelynek állapota a W3C szerint befejezéshez közeli.

1. fejezet - Alapfogalmak

Bevezetés

Ebben a fejezetben az XML Schema fogalomrendszerét tekintjük át, amelynek ismerete elengedhetetlen sémák a gyakorlatban történő használatához. A fejezetben mellőzzük az XML szintaxist – csupán egyetlen szakaszban mutatunk ilyet –, az alapfogalmak jelentésére koncentrálunk.

Sémák és sémadokumentumok

Az XML Schema keretrendszerében a sémák sémakomponenseknek hívott alkotórészekből álló absztrakt objektumok. Az [XML Schema: Structures] specifikáció egy XML formátumot határoz meg a sémák ábrázolásához, a sémák ennek megfelelő XML reprezentációit nevezzük sémadokumentumoknak. A gyakorlatban a sémák ezen megjelenési formájával dolgozunk, ezért a séma és sémadokumentum fogalmát gyakran egymással felcserélhetőnek tekintjük, noha szigorú értelemben ez pontatlan.

Sémakomponensek

Minden séma olyan, sémakomponenseknek nevezett alkotórészekből áll, amelyeknek a következő három csoportját különböztetjük meg fontosságuk alapján:

  • Elsődleges sémakomponensek:

    • elemdeklarációk

    • tulajdonság-deklarációk

    • típusdefiníciók

  • Másodlagos sémakomponensek:

    • modellcsoport-definíciók

    • tulajdonságcsoport-definíciók

    • azonossági megszorítások definíciói

    • jelölésdeklarációk

  • Segédkomponensek:

    • kommentárok

    • modellcsoportok

    • részecskék

    • helyettesítők

A könyvben a jelölésdeklarációk kivételével tárgyalásra kerül valamennyi sémakomponens. Minden komponenst egy elem ábrázol a sémadokumentumokban.

Bizonyos sémakomponenseknek, egészen pontosan a deklarációknak és definícióknak lehet azonosítóként szolgáló neve, amely lehetővé teszi a komponensre történő hivatkozást. Az elsődleges sémakomponensek közül a deklarációkhoz kötelezően tartozik név, a típusdefiníciókhoz viszont csak opcionálisan. A másodlagos sémakomponensek mindegyikét kötelező névvel azonosítani. A segédkomponensek egyikének sincs neve, ezek a kommentárok kivételével minden esetben más komponensek részét alkotják, felhasználásuk kizárólag az előfordulásuk helyén történik.

A sémakomponensek neve egy kettőspont karaktert nem tartalmazó érvényes XML név. (Az XML névtereket tárgyaló [XML Names] dokumentum az ilyen nevekre az NCName kifejezést használja.) Sémadokumentumokban a komponenseket ábrázoló elemek name tulajdonságának értékeként kell megadni a neveket.

Minden sémadokumentumhoz tartozhat egy cél-névtér, amelynek értéke egy, az [XML Names] szabványnak megfelelő névtér név. Cél-névtér használata esetén a sémakomponensek nevei az általa meghatározott névtérbe tartoznak, hiányában pedig nem tartoznak egyetlen névtérbe sem.

Megjegyezzük, hogy azonos fajta sémakomponensek esetén követelmény a nevek egyedisége a sémában. Míg például minden elemdeklaráció neve különböző kell, hogy legyen, egy elemdeklaráció neve megegyezhet például egy típusdefiníció nevével.

Sémák ábrázolása sémadokumentumokban

A sémakomponenseket ábrázoló XML elemek nevei a http://www.w3.org/2001/XMLSchema URI által azonosított névtérbe tartoznak. Az ugyancsak ebbe a névtérbe tartozó schema nevű elem szolgál a sémadokumentumok gyökérelemeként. A gyakorlatban az xs vagy az xsd előtaghoz szokás a fenti névtér nevet egy névtér deklarációban hozzákötni, mi a továbbiakban az xs előtagot használjuk.

A sémadokumentumok alakja általánosan a következő:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="URI">
	sémakomponens(ek)
</xs:schema>

A schema elemhez opcionális a cél-névteret meghatározó targetNamespace tulajdonság, gyermekként pedig a következő sémakomponenseket tartalmazhatja tetszőleges számban és sorrendben:

  • minden elsődleges sémakomponenst,

  • a másodlagos sémakomponensek közül a modellcsoport-definíciókat, tulajdonságcsoport-definíciókat és jelölésdeklarációkat,

  • a segédkomponensek közül a kommentárokat.

Típusrendszer

Az XML Schema fogalomrendszerében központi szerepet játszanak a típusdefiníciók, amelyek az elemekhez és tulajdonságokhoz kötődnek. Minden deklarált elemhez és tulajdonsághoz tartozik egy típusdefiníció, amely a deklarációban határozható meg. A szabvány egy hierarchikus típusrendszert használ, amelyben lehetővé teszi a felhasználó számára típusdefiníciók létrehozását. A következő szakaszokban a típusrendszer alapfogalmait mutatjuk be röviden.

Típusdefiníciók

Minden típust egy típusdefiníció határoz meg, amelyet egy típusdefiníciós sémakomponens ábrázol. A típusoknak (típusdefinícióknak) lehet neve, amely lehetővé teszi a típusra (típusdefinícióra) történő hivatkozást, így a többszöri felhasználást. A név azonban nem kötelező, névtelen típusoknak (névtelen típusdefinícióknak) nevezzük azokat a típusokat (típusdefiníciókat), amelyekhez nem tartozik név. Ezek a sémában egyetlen helyen kerülnek felhasználásra.

A továbbiakban a típus és típusdefiníció fogalmakat egyenértékűnek tekintjük, mivel a típus és definíciója között kölcsönösen egyértelmű megfeleltetés van.

Egyszerű és komplex típusok

A típusok (típusdefiníciók) révén fogalmazhatóak meg a példányokban előforduló elemekre és tulajdonságokra vonatkozó érvényességi megszorítások. Az XML Schema kétféle típust (típusdefiníciót) különböztet meg: egyszerű és komplex típusokat (típusdefiníciókat). A kétféle típusfogalom lényegesen különbözik.

Egyszerű típusok.  Minden egyszerű típushoz egy olyan értékhalmaz tartozik, amelynek elemeit szöveges literálok ábrázolják. Az XML Schema számos beépített egyszerű típust biztosít (például boolean, date, double és int), amelyek megfelelnek a programozási nyelvek és az adatbázis-kezelő rendszerek szokásos adattípusainak. Egyszerű típusokat használhatunk tulajdonságok és elemek típusaként egyaránt, az egyszerű típusú elemeknek azonban nem lehetnek tulajdonságaik. Az egyszerű típusok értelemszerűen nem teszik lehetővé tartalomként elemek használatát sem. Az egyszerű típusok alapfogalmait és gyakorlati alkalmazását külön fejezetek tárgyalják.

Komplex típusok.  Komplex típusok kizárólag az elemekhez állnak rendelkezésre. A komplex típusok teszik lehetővé tartalomként elemek, valamint tulajdonságok használatát. Az egyszerű típusoktól eltérően a szabvány nem biztosít beépített komplex típusokat. A komplex típusokat részletesen a Komplex típusok című fejezet tárgyalja.

Típushierarchia

Egy kivételtől eltekintve minden típusdefiníció egy másik típusdefiníció megszorítása vagy kiterjesztése, amelyet alap-típusdefiníciónak nevezünk, az ennek megfelelő típus pedig az alaptípus. (Hamarosan látni fogjuk, hogy az egyszerű típusok esetén valójában két további származtatási lehetőség is adott.) A típusdefiníciók közötti ezen kapcsolatok egy hierarchiát határoznak meg.

A kivételt jelentő típusdefiníció a hierarchia csúcsán lévő, amelynek ur-típus-definíció a neve.[1] Ez a típusdefiníció implicit módon része minden sémának. Az ur-típus-definíciónak az anyType nevű komplex típus felel meg. Az ur-típus-definíció (anyType típus) a hierarchia gyökerét jelenti, amelyből az összes többi típusdefiníció (típus) származik.

Létezik egy egyszerű ur-típus-definíciónak nevezett olyan egyszerű típus-definíció is, amely a komplex ur-típus-definíció egy speciális megszorítása, és amelyből az összes egyszerű típus-definíció származik. A megfelelő egyszerű típus neve anySimpleType.

1.1. ábra - Típushierarchia

Típushierarchia

Alább a komplex és egyszerű típus-definíciókra is megadjuk a hierarchiába történő beépülésük lehetséges módjait.

Komplex típus-definíciók a hierarchiában.  Az ur-típus-definíciótól különböző minden komplex típus-definícióra az alábbiak egyike teljesül:

  • egy egyszerű típus-definíció kiterjesztése,

  • egy másik komplex típus-definíció kiterjesztése,

  • egy másik komplex típus-definíció megszorítása.

Egyszerű típus-definíciók a hierarchiában.  Az egyszerű ur-típus definíciótól különböző minden egyszerű típus-definícióra az alábbiak egyike teljesül:

  • egy másik egyszerű típus-definíció megszorítása,

  • egy másik egyszerű típus-definíció felhasználásával listaképzéssel származtatott (ekkor a másik típusdefinícióra az elem-típusdefiníció kifejezést használjuk),

  • más egyszerű típus-definíciók felhasználásával unióképzéssel származtatott (ekkor a többi típusdefinícióra a tag-típusdefiníció kifejezést használjuk).

Megjegyezzük, hogy a listaképzéssel és unióképzéssel származtatott típusdefiníciók is az egyszerű ur-típus-definíció megszorításaiként tekintendők.

Egyszerű és komplex típus-definíciók esetében is korlátozhatja a felhasználó adott típusdefiníció új típusdefiníciók létrehozásához alap-típusdefinícióként (egyszerű típusdefiníciók esetén alap-, elem- vagy tag-típusdefinícióként) történő felhasználását. (Erre szolgál a típusdefiníciós elemek final tulajdonsága.)



[1] A ur- egy német előtag, amelynek jelentése primitív, eredeti. Mivel az eredeti, angol nyelvű szakkifejezésben (ur-type definition) is idegen szóként szerepel, mi is megtartjuk és nem használunk helyette magyar megfelelőt.

2. fejezet - Egyszerű típusok (adattípusok) fogalmai

Bevezetés

Az XML Schema lehetőségei közül az adattípusoknak is nevezett egyszerű típusok felépítése mondható a legabsztraktabbnak. Noha a beépített adattípusok használata egyszerű, a származtatás mechanizmusának megértése a fogalmakban történő alaposabb elmélyedést igényel. Ezért egy külön fejezetet szentelünk az egyszerű típusok elméleti megalapozásának. Az egyszerű típusok származtatásának gyakorlatát a következő fejezet tárgyalja.

Adattípusok fajtái

Még az adattípus fogalmának pontos meghatározása előtt megadjuk az adattípusok olyan felosztásait, amelyek mindegyikénél bármely adattípus egyértelműen sorolható pontosan az egyik kategóriába.

Primitív és származtatott adattípusok

Primitív adattípusok

Így nevezzük azokat az adattípusokat, amelyek definiálásához nem kerülnek felhasználásra más adattípusok. Ilyenek például a boolean, double és string beépített adattípusok.

Származtatott adattípusok

Így nevezzük azokat az adattípusokat, amelyek definiálása más adattípusok felhasználásával (megszorítással, lista- vagy unióképzéssel) történik. Ilyenek például az integer és normalizedString beépített adattípusok, az előbbi a decimal, az utóbbi pedig a string primitív adattípusból származtatott megszorítással.

Beépített és felhasználói származtatott adattípusok

Beépített adattípusok

Így nevezzük azokat az adattípusokat, amelyeket az [XML Schema: Datatypes] specifikáció definiál. Ilyenek például a boolean, integer és time adattípusok.

Felhasználói származtatott adattípusok

Így, vagy röviden felhasználói adattípusoknak nevezzük a felhasználók által definiált adattípusokat.

Atomi, lista és unió adattípusok

Atomi adattípusok

Az ilyen adattípusok értékeit a specifikáció oszthatatlannak tekinti. Atomi adattípusok például a double és string beépített adattípusok.

Lista adattípusok

Az ilyen adattípusok értékei egy adott, elemtípusnak nevezett atomi adattípus értékeiből álló véges sorozatok. A lista adattípusok lexikális terét az elemtípus literáljaiból álló olyan listák alkotják, amelyekben az elemeket szóköz karakterek választják el. Lista adattípusok kanonikus lexikális reprezentációja egy olyan olyan lexikális forma, amelyben a listát alkotó elemek mindegyike megfelel az elemtípus kanonikus reprezentációjának. Lista adattípusok az IDREF, ENTITIES és NMTOKENS beépített adattípusok.

Unió adattípusok

Az ilyen adattípusok értékhalmaza más, tagtípusoknak nevezett adattípusok értékhalmazainak halmazelméleti uniója. A lexikális tér hasonlóan a tagtípusok lexikális tereinek halmazelméleti uniója. A kanonikus lexikális reprezentáció a tagtípusok kanonikus lexikális reprezentációja alapján definiálható. A beépített adattípusok egyike sem unió adattípus.

Adattípus fogalma

Minden adattípust egy olyan rendezett hármas határoz meg, amelyet az alábbi halmazok alkotnak:

  • Az értékek halmaza, az úgynevezett értéktér.

  • Az értékeket ábrázoló literálok halmaza, az úgynevezett lexikális tér.

  • Az értéktéret, az egyedi értékeket vagy literálokat jellemző adattípus-tulajdonságok értékei.

Értéktér

Az értéktér az adattípus-értékek halmaza, amely többféle módon határozható meg:

  • Axiomatikusan (lásd a primitív adattípusokat).

  • Az értéktér elemeinek felsorolásával (lásd a felsorolásokat).

  • Egy másik adattípus értékterének korlátozásával (lásd a megszorítással származtatott adattípusokat).

  • Egy vagy több adattípus értékteréből származó értékek kombinálásával (lásd a lista és unió adattípusokat).

Minden adattípushoz a fenti megoldások valamelyike használt. Megjegyezzük, hogy a primitív adattípusok értékterei diszjunktak.

Lexikális tér

A lexikális tér az adattípus értékeit reprezentáló karakterláncok (literálok) halmaza. Az XML Schema literáljainak felírása a programozási nyelvek és adatbázis-kezelő rendszerek hagyományait követi.

Az értéktér minden elemét a lexikális tér egy vagy több literálja is ábrázolhatja. Például a decimal adattípusnál az 1, +1, 1.0, 01 literálok ugyanazt az értéket jelölik.

A kanonikus lexikális reprezentáció a lexikális tér egy olyan részhalmaza, amely kölcsönösen egyértelműen feleltethető meg az értéktér elemeinek.

[Megjegyzés]Kanonikus XML

Az alkalmazások számára fizikailag különböző XML dokumentumok ekvivalensek lehetnek információtartalmuk szempontjából. Az ekvivalencia okai lehetnek például az alábbiak:

  • Tartalom nélküli elem megadható közvetlenül egymást követő nyitó- és zárócímkével vagy üreselem címkével is.

  • Nem szignifikáns az elemekhez tartozó tulajdonság-specifikációk sorrendje.

  • A tulajdonságérték-normalizálás különböző tulajdonságértékeknél eredményezheti ugyanazt a normalizált tulajdonságértéket.

[XML-C14N] egy olyan algoritmust definiál, amellyel minden XML dokumentum egyértelműen alakítható át egy kanonikus alaknak nevezett ekvivalens XML dokumentummá. Ekvivalenseknek tekinthetők azok a dokumentumok, amelyek kanonikus alakja megegyezik. [XML-C14N] azonban szigorúan DTD-alapú, így a kanonikus alak létrehozásához nem kerül felhasználásra a fenti kanonikus lexikális reprezentáció.

Adattípus-tulajdonságok

Az adattípus-tulajdonságok az adattípusokat meghatározó tulajdonságok.[2] Az adattípusok definiálása az adattípus-tulajdonságok értékeinek rögzítésével történik, amelyek együtt meghatározzák az adattípus értékterét és jellemzőit.

Az adattípus-tulajdonságoknak a következő két fajtáját különböztetjük meg:

Adattípus-alaptulajdonságok

Olyan absztrakt tulajdonságok, amelyek szemantikusan jellemzik az értékteret.

Korlátozó adattípus-tulajdonságok

A korlátozó adattípus-tulajdonságok típusdefiníciók megszorítással történő származtatásához állnak rendelkezésre. Olyan opcionális tulajdonságok, amelyeket egy adattípusra alkalmazva korlátozni lehet annak értékterét. Az értéktér korlátozása egyben a lexikális tér korlátozását is jelenti. Ilyen módon az XML Schema típusdefiníciós mechanizmusának lelkét jelentik, felsorolásukat a Korlátozó adattípus-tulajdonságok című függelék tartalmazza a könyv végén.

Adattípus-alaptulajdonságok

Az adattípus-alaptulajdonságok az értéktér absztrakt matematikai (halmazelméleti) jellemzőit adják meg. A sémákban ezek explicit módon nem jelennek meg, hanem [XML Schema: Datatypes] rögzíti minden beépített adattípusra minden egyes adattípus-alaptulajdonság értékét, pontosan előírja továbbá azt is, hogy új adattípus származtatása során hogyan határozandó meg ahhoz az adattípus-alaptulajdonságok értéke.

A gyakorlat szempontjából másodlagos fontosságúnak tekinthetjük az adattípus-alaptulajdonságokat, mert nincs lehetőség a sémákban értékük közvetlen előírására. Ennek ellenére érdemes időt szánni rájuk, hiszen az adattípusok alaptermészetére világítanak rá. Mivel a specifikációban meglehetősen körülményesen – matematikai definíciók bevezetésével – történik az adattípus-alaptulajdonságok tárgyalása, az egyszerűség kedvéért itt közérthető módon próbáljuk a lényeget visszaadni.

Négy adattípus-alaptulajdonság van, amelyeket a következő szakaszokban mutatunk be.

bounded

A logikai értékű bounded adattípus-alaptulajdonság azt jelzi, hogy az adattípus korlátos-e. Értéke true akkor, ha az adattípus korlátos, egyébként false.

Egy rendezett adattípust korlátosnak nevezünk akkor, ha létezik olyan érték, amely az értéktér minden egyes értékénél kisebb vagy egyenlő vagy szigorúan kisebb, valamint létezik olyan érték, amely az értéktér minden eleménél nagyobb vagy egyenlő vagy szigorúan nagyobb. Ez a két érték nem feltétlenül tartozik az értéktérhez származtatott típus esetén!

Egy atomi származtatott adattípus esetén true az adattípus-alaptulajdonság értéke akkor, ha adattípus-tulajdonságai között van a minInclusive vagy a minExclusive, valamint a maxInclusive vagy a maxExclusive, egyébként pedig false.

Egy lista adattípus esetén true az adattípus-alaptulajdonság értéke akkor, ha adattípus-tulajdonságai között van a length vagy a minLength és a maxLength, egyébként pedig false. (Azaz lista adattípusok esetén a korlátosság az elemek számának korlátosságát jelenti.)

Egy unió adattípusnál true az adattípus-alaptulajdonság értéke akkor, ha true minden tagtípus esetén is, továbbá van olyan (az anySimpleType típustól különböző) adattípus, amely őse valamennyi tagtípusnak, egyébként pedig false.

A beépített (rendezett) adattípusok közül korlátos például a double, float és long, nem korlátos a date és positiveInteger.

cardinality

Az adattípus értékterének számosságát jelző adattípus-alaptulajdonság, amelynek lehetséges értékei finite (véges) és countably infinite (megszámlálhatóan végtelen). Az adattípus értékterének számosságát az adattípus számosságának is nevezzük.

Atomi származtatott típusok esetén meglehetősen bonyolult módon határozandó meg az adattípus-alaptulajdonság értéke, csupán a teljesség kedvéért adjuk meg ennek pontos menetét. Egy atomi származtatott típusnál finite az adattípus-tulajdonság értéke akkor, ha az alaptípus esetén is finite. Az adattípus-alaptulajdonság értéke finite akkor is, ha az alaptípus esetén countably infinite, de teljesül az alábbi feltételek valamelyike, egyébként pedig countably infinite:

  1. Az adattípus-tulajdonságok között van a length, maxLength és totalDigits közül valamelyik.

  2. Teljesül az alábbiak mindegyike:

    1. Az adattípus-tulajdonság között van a minInclusive vagy a minExclusive.

    2. Az adattípus-tulajdonságok között van a maxInclusive vagy a maxExclusive.

    3. Teljesül az alábbiak valamelyike:

      1. Az adattípus-tulajdonságok között van a fractionDigits.

      2. Az alaptípus a date, gYearMonth, gYear, gMonthDay, gDay, gMonth adattípusok valamelyike, vagy ezekből származtatott adattípus.

Egy lista adattípusnál finite az adattípus-alaptulajdonság értéke akkor, ha adattípus-tulajdonságai között van a length vagy a minLength és a maxLength, egyébként pedig countably infinite.[3]

Egy unió adattípusnál finite az adattípus-alaptulajdonság értéke akkor, ha finite minden tagtípus esetén is, egyébként az értéke countably infinite.

A beépített adattípusok közül például a boolean, double és long adattípusoknál is finite az adattípus-alaptulajdonság értéke, míg például a date, duration és string adattípusoknál countably infinite.

numeric

Azokat az adattípusokat tekintjük numerikus adattípusoknak, amelyek értékterének elemei számok. A logikai értékű numeric adattípus-alaptulajdonság azt jelzi, hogy az adattípus numerikus-e. Értéke true akkor, ha az adattípus numerikus, egyébként false.

Egy atomi származtatott adattípus pontosan akkor numerikus, ha az alaptípusa is az. (Vagyis minden atomi származtatott adattípus az alaptípusától örökli a numeric adattípus-alaptulajdonság értékét.) A lista adattípusok nem numerikus adattípusok. Egy unió adattípus akkor és csak akkor numerikus, ha minden tagtípusa numerikus.

A beépített adattípusok közül numerikus például a long, double és float, nem numerikus a date, duration és a string adattípus.

ordered

A specifikáció számos beépített adattípus esetén egy rendezést értelmez az értéktér elemei között, ezeket az adattípusokat nevezzük a továbbiakban rendezett adattípusoknak. Az ordered adattípus-alaptulajdonság jelzi, hogy az adattípus rendezett-e, rendezés esetén annak jellegét megadva. Magát a rendezést az adattípusok leírásánál határozza meg pontosan a specifikáció, így teszünk mi is.

Az alábbi két fajta rendezést használja a specifikáció:

szigorú részbenrendezés

A matematikai szakkifejezés egy irreflexív, aszimmetrikus és tranzitív relációt jelent. A szigorú részbenrendezés szemléletesen egy olyan reláció, amelyet a < szimbólummal szokás jelölni, amelyben azonban nem feltétlenül lehet bármely két elemet összehasonlítani.

Ha két elem összehasonlítható a rendezési relációban, akkor a < jelölés kapcsán megszokott (szigorúan) kisebb és (szigorúan) nagyobb kifejezéseket használjuk viszonyuk kifejezésére.

szigorú teljes rendezés

A matematikai szakkifejezés egy olyan szigorú részbenrendezést jelent, amelyben bármely két elem összehasonlítható, azaz bármely két elem esetén vagy vagy .

Az adattípus-alaptulajdonság lehetséges értékei:

false

Azt jelenti, hogy az értékéren nem értelmezett rendezés.

partial

Azt jelenti, hogy az értéktéren egy szigorú részbenrendezés értelmezett.

total

Azt jelenti, hogy az értéktéren egy szigorú teljes rendezés értelmezett.

Minden atomi származtatott adattípus az alaptípusától örökli az ordered adattípus-alaptulajdonság értékét. Lista adattípusok esetén az adattípus-alaptulajdonság értéke false. Unió adattípusok esetén az adattípus-alaptulajdonság értéke partial az alábbi kivételekkel:

  • Ha minden tagtípus származtatása ugyanabból az anySimpleType típustól különböző adattípusból történik, akkor az ordered adattípus-alaptulajdonság értéke a közös őstől öröklődik.

  • Ha az ordered adattípus-alaptulajdonság értéke minden tagtípus esetén false, akkor az unió adattípus esetén is false.

Például nem értelmezett rendezés a boolean, hexBinary és string beépített adattípusok esetén. Szigorú részbenrendezés értelmezett csak a duration beépített adattípus esetén, mivel nem összehasonlíthatóak például a P1M (1 hónap) és P30D (30 nap) literálokkal ábrázolt értékek. A primitív adattípusok közül kizárólag a decimal esetén értelmezett szigorú teljes rendezés.

Példa: a decimal adattípus

Az alapfogalmak szemléltetéséhez ebben a szakaszban egy beépített primitív adattípust mutatunk be, meghatározva az értékterét, lexikális terét, kanonikus lexikális reprezentációját, adattípus-alaptulajdonságainak értékét, valamint az adattípusra alkalmazható korlátozó adattípus-tulajdonságokat.

2.1. példa - A decimal adattípus

A decimal adattípus egy atomi beépített primitív adattípus.

Értéktér

Az értéktér az alakban kifejezhető számok halmaza, ahol egész, pedig nemnegatív egész.

Lexikális tér

A lexikális tér elemei olyan decimális számjegyekből álló karakterláncok, amelyek opcionálisan tartalmazhatnak egy, a tizedesvessző helyét jelölő pont karaktert, első karakterként pedig egy előjel karaktert. Érvényes literálok például a következő karakterláncok: +42, 1000.00, 3.141593, -0.7071068

Kanonikus lexikális reprezentáció

A kanonikus lexikális reprezentáció az alábbi módon definiált:

  • Kötelező a pont karakter használata, amelynek mindkét oldalán legalább egy számjegy megadása kötelező.

  • Előjelként tilos a + karakter megadása.

  • Tilos vezető és a decimális pontot követő szám végi nullák használata a következő kivételtől eltekintve: egyetlen nulla számjegy önmagában állhat a decimális pont mindkét oldalán.

A fentiek alapján például a 0 számot a 0.0 literál ábrázolja.

Adattípus-alaptulajdonságok

Az alábbiak az adattípus-alaptulajdonságok értékei:

  • A bounded adattípus-alaptulajdonság értéke false (az adattípus nem korlátos).

  • A cardinality adattípus-alaptulajdonság értéke countably infinite (az értéktér számossága megszámlálhatóan végtelen).

  • A numeric adattípus-alaptulajdonság értéke true (az értéktér elemei számok).

  • A ordered adattípus-alaptulajdonság értéke total (az értéktéren egy szigorú teljes rendezés értelmezett).

Alkalmazható korlátozó adattípus-tulajdonságok

A következő korlátozó adattípus-tulajdonságok alkalmazhatóak az adattípusra:

enumeration
fractionDigits
maxExclusive
maxInclusive
minExclusive
minInclusive
pattern
totalDigits
whiteSpace




[2] Az adattípus-tulajdonság kifejezést a továbbiakban az angol facet kifejezés helyett használjuk, amelynek ebben a környezetben való előfordulásának nem létezik még elterjedten használt és széles körben elfogadott magyar megfelelője.

[3] Ez a megfogalmazás a szerző véleménye szerint hiányos és hibás, mivel az értéktér végességéhez azt is meg kellene követelni, hogy az elemtípus cardinality adattípus-alaptulajdonságának értéke finite legyen. A véleményt alátámasztani látszik az, hogy a vitatott megfogalmazás a szabvány következő, ajánlásként még nem elfogadott verziójában már ennek megfelelően kiegészítve szerepel.

3. fejezet - Egyszerű típusok (adattípusok) használata és származtatása

Bevezetés

Ebben a fejezetben az egyszerű típusok (adattípusok) gyakorlati használatát tekintjük át. Szorosan kapcsolódnak a témához a könyv végén található Beépített adattípusok és Korlátozó adattípus-tulajdonságok című függelékek.

Beépített adattípusok

Az [XML Schema: Datatypes] specifikáció definiálja a minden sémában rendelkezésre álló beépített adattípusokat. Ezek mindegyikét egy URI azonosítja, amelyben a bázis-URI http://www.w3.org/2001/XMLSchema, az erőforrásrész-azonosító pedig az adattípus neve. Például a beépített date adattípust a http://www.w3.org/2001/XMLSchema#date URI azonosítja. A beépített adattípusokra való hivatkozásokhoz a sémadokumentumokban minősített neveket használunk, mint például xs:date. A beépített adattípusok részletes ismertetését a Beépített adattípusok című függelék tartalmazza.

Literálok használata a példányokban

Az adattípusok értékeit a példányokban literálok ábrázolják. A Beépített adattípusok című függelékben megadjuk minden egyes beépített adattípus literáljainak szintaxisát. Mivel minden felhasználói adattípus a beépített adattípusokból származtatott, ezekhez is pontosan meghatározott a literálok formája.

Megjegyezzük, hogy a lista adattípusok literáljai az elemtípus literáljaiból képzett olyan listák, amelyekben az elemeket szóköz karakterek választják el.

Literálok ábrázolásánál a felhasználó számára bizonyos szabadság biztosított a whitespace karakterek használata tekintetében, amely szabályozható.

Whitespace karakterek kezelése

Az [XML 1.0] specifikáció kötelezővé teszi az XML feldolgozók számára tulajdonságértékek normalizálását. A feldolgozók az érvényesség ellenőrzését a normalizált tulajdonságértékeken végzik el, az alkalmazásoknak ugyancsak a normalizált értékeket adják tovább.

A fenti tulajdonságérték-normalizálást végrehajtják a sémafeldolgozók is a tulajdonságértékek érvényességének ellenőrzése előtt.

Az XML Schema elemekhez is lehetővé teszi adattípusok használatát, amely a tulajdonságokkal egységesen történő kezelés biztosításához szükségessé teszi a whitespace normalizálás megfelelő értelmezését és kiterjesztését az elemekre is.

Egyszerű típusú elemek és tulajdonságok normalizált értéke normalizálással nyerhető:

  • A normalizálást tulajdonságok esetében a tulajdonságértékre kell végrehajtani az [XML 1.0] specifikációban meghatározott tulajdonságérték-normalizálás végrehajtás után.

  • A normalizálást elemek esetén a tartalomként megjelenő szövegre kell végrehajtani, amelynek során figyelmen kívül kell hagyni az elemben tartalmazott megjegyzéseket és feldolgozási utasításokat.

A sémafeldolgozók érvényesítést az elemek és tulajdonságok normalizált értékén végeznek.

Az alábbi normalizálások definiáltak:

preserve (megőrzés)

Nincs whitespace normalizálás, a normalizálandó érték változatlan marad.

replace (helyettesítés)

A normalizálandó értékben minden TAB (U+0009), LF (U+000A) és CR (U+000D) karaktert egy szóköz karakterrel (U+0020) kell helyettesíteni.

collapse (összevonás)

Végre kell hajtani a replace alatt leírt helyettesítéseket, majd a kapott értékben egyetlen szóköz karakterre kell cserélni a szóközökből álló összefüggő karaktersorozatokat, végül az eredmény elejéről és végéről el kell hagyni az esetleges szóköz karaktert.

A whiteSpace korlátozó adattípus-tulajdonság alkalmazásával szabályozható a normalizálás, amelynek értékeként a fentieknek megfelelő preserve, replace és collapse adható meg.

A string adattípus kivételével minden beépített atomi adattípus esetén collapse a whiteSpace adattípus-tulajdonság értéke, amely nem változtatható meg.

A string adattípus esetén preserve a whiteSpace adattípus-tulajdonság értéke, az adattípusból történő származtatás során azonban mindhárom lehetséges érték megadható ezen adattípus-tulajdonság értékeként.

Vegyük észre, hogy tulajdonságértékeket ilyen módon kétszer normalizálja a sémafeldolgozó. A replace vagy collapse normalizálás végrehajtása az XML 1.0 tulajdonságérték-normalizálás után azonban nem felesleges, további változást nem eredményező művelet. Karakterhivatkozások használata révén maradhatnak ugyanis TAB, CR és LF karakterek az XML 1.0 tulajdonságérték-normalizált tulajdonságértékben, amelyeket replace és collapse szóköz karakterekre cserél.

3.1. példa - Elem normalizált értéke

Legyen a number elem integer típusúként deklarált. Az elem egy lehetséges előfordulása például az alábbi:

<number>
    12<!-- This is a comment -->43
</number>

Az integer beépített adattípus esetén a whiteSpace adattípus-alaptulajdonság értéke collapse, így az elem normalizált értéke 1234.


3.2. példa - Elem normalizált értéke

Ha a title elem string típusúként deklarált, akkor például a

<title xml:lang="hu">
    Az ember, aki <!-- This is a comment --> csütörtök
    volt</title>

elem normalizált értéke a következő:

    Az ember, aki  csütörtök
    volt

Adattípusok definiálása

Adattípusok definiálására egy olyan sémakomponens szolgál, amelyeket a sémadokumentumokban a simpleType elem ábrázol. A sémában két helyen helyezhető el típusdefiníció:

  • Felső szinten, azaz közvetlenül a schema elem gyermekeként megjelenő típusdefinícióban kötelező egy név megadása a name tulajdonság értékeként, amely a sémában a típusdefiníciót egyedi módon azonosítja. A név lehetővé teszi a típusra történő hivatkozást.

  • Elem- és tulajdonság-deklaráció valamint típusdefiníció részeként is megjelenhet adattípus definíciója, amelyhez tilos név megadása. Ilyenkor névtelen típusdefinícióról beszélünk, a megfelelő típust pedig névtelen típusnak nevezzük. A névtelen típusok felhasználása a típusdefiníció helyén történik.

Megjegyezzük, hogy az adattípusok és a komplex típusok nevei különbözőek kell, hogy legyenek minden sémában.

3.3. példa - Adattípus felső szintű definíciója és felhasználása

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:simpleType name="grade">
        <xs:restriction base="xs:integer">
            <xs:minInclusive value="1"/>
            <xs:maxInclusive value="5"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:element name="grade" type="grade"/>
    ...
</xs:schema>


3.4. példa - Névtelen adattípus definíciója és felhasználása

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:attribute name="currency">
        <xs:simpleType>
            <xs:restriction base="xs:token">
                <xs:enumeration value="EUR"/>
                <xs:enumeration value="HUF"/>
            </xs:restriction>
        </xs:simpleType>
    </xs:attribute>
    ...
</xs:schema>


A típusdefiníciós simpleType elem a következő, a származtatás módját meghatározó elemek egyikét kell, hogy tartalmazza:

  • restriction (megszorítás)

  • list (listaképzés)

  • union (unióképzés)

Adattípusok származtatása megszorítással

Típusdefiníció származtatása történhet egy alap-típusdefinícióból megszorítással, ekkor a típusdefiníciós simpleType elemben a restriction elemet kell megadni. Az alap-típusdefiníció kétféle, egymást kizáró módon jelezhető:

  • A restriction elem base tulajdonságának értékeként egy egyszerű típus-definíció neve adható meg.

  • A restriction elem gyermekeként megadható egy névtelen típusdefiníciós simpleType elem.

A restriction elemben olyan korlátozó adattípus-tulajdonságok értékeit lehet meghatározni, amelyek az alaptípus értékterét szűkítik.

Minden korlátozó adattípus-tulajdonsághoz olyan elemeket kell használni, amelyek value tulajdonsága hordozza a korlátozó adattípus-tulajdonság értékét. (Megjegyezzük, hogy az adattípus-tulajdonságok többségének értékét egyetlen elem szolgáltatja, de van két olyan, a pattern és az enumeration, amelyekhez egynél több elem adható meg.) Ezek az elemek általában üresek, tartalomként megengedett azonban a Kommentárok című szakaszban tárgyalt annotation elem. Ha az alap-típusdefiníció egy névtelen típusdefiníció, akkor az adattípus-tulajdonságok elemei a simpleType elemet kell, hogy kövessék. A Korlátozó adattípus-tulajdonságok című függelék mutatja be részletesen a rendelkezésre álló adattípus-tulajdonságokat.

A simpleType elem a fentieknek megfelelő formáját a következőképpen foglalhatjuk össze (a felső szintű típusdefiníciót adjuk meg, névtelen típusdefinícióban el kell hagyni a name tulajdonságot):

<simpleType name="név">
    <xs:restriction base="alaptípus">  (felső színtű típusdefiníció használata)
        korlátozó adattípus-tulajdonságok értékeit meghatározó elemek
    </xs:restriction>
</simpleType>

<simpleType name="név">
    <xs:restriction>
        <xs:simpleType>  (névtelen típusdefiníció használata)
            ...
        </xs:simpleType>
        korlátozó adattípus-tulajdonságok értékeit meghatározó elemek
    </xs:restriction>
</simpleType>
                    

Alaptípusként használható atomi, lista és unió adattípus.

[Fontos]Fontos

Ha az alaptípus egy lista adattípus, akkor csak a következő korlátozó adattípus-tulajdonságok állnak rendelkezésre megszorítással történő származtatáshoz:

enumeration
length
maxLength
minLength
pattern
whitespace

A fenti adattípus-tulajdonságok ilyenkor magukra a listákra vonatkoznak, nem az egyes elemekre.

[Fontos]Fontos

Ha az alaptípus egy unió adattípus, akkor kizárólag a következő két korlátozó adattípus-tulajdonság áll rendelkezésre megszorítással történő származtatáshoz:

enumeration
pattern

3.5. példa - Adattípus származtatása megszorítással

Az alábbi típusdefinícióban a minInclusive és maxInclusive adattípus-tulajdonságokat alkalmazzuk a beépített integer adattípusra, amelyekkel az alaptípus értékterét egy tartományra korlátozzuk:

<xs:simpleType name="percent">
    <xs:restriction base="xs:integer">
        <xs:minInclusive value="1"/>
        <xs:maxInclusive value="100"/>
    </xs:restriction>
</xs:simpleType>

Az adattípus értékterét az 1, …, 100 egész számok alkotják.


3.6. példa - Adattípus származtatása megszorítással

Az alábbi típusdefinícióban a minInclusive és fractionDigits adattípus-tulajdonságokat alkalmazzuk a beépített decimal adattípusra:

<xs:simpleType name="price">
    <xs:restriction base="xs:decimal">
        <xs:minInclusive value="0"/>
        <xs:fractionDigits value="2"/>
    </xs:restriction>
</xs:simpleType>

Az adattípus értékterének elemei az olyan (decimal típusú) nemnegatív számok, ahol a tizedespontot legfeljebb két értékes számjegy követi. Érvényes literálok például a következő karakterláncok: 0, 0.0, 9.670, 18.23, 3397000


3.7. példa - Adattípus származtatása megszorítással

Az alábbi típusdefinícióban a pattern adattípus-tulajdonságot alkalmazzuk a beépített string adattípusra:

<xs:simpleType name="isbn13">
    <xs:restriction base="xs:string">
        <xs:pattern value="[0-9]{13}"/>
    </xs:restriction>
</xs:simpleType>

Az adattípus értékterének elemei a 13-jegyű ISBN-számok, azaz a pontosan 13 decimális számjegy karakterből álló karakterláncok.


3.8. példa - Egyszerű típus definíciója

Az alábbi típusdefinícióban a pattern adattípus-tulajdonságot alkalmazzuk a beépített anyURI adattípusra:

<xs:simpleType name="myURI">
    <xs:restriction base="xs:anyURI">
        <xs:pattern value="ftp://.*"/>
        <xs:pattern value="http(s)?://.*"/>
    </xs:restriction>
</xs:simpleType>

Az adattípus értékterét az ftp://, http:// és https:// kezdőszeletű URI karakterláncok alkotják.

Megjegyezzük, hogy a fenti típusdefinícióval ekvivalens a következő:

<xs:simpleType name="myURI">
    <xs:restriction base="xs:anyURI">
        <xs:pattern value="(ftp://.*)|(http(s)?://.*)"/>
    </xs:restriction>
</xs:simpleType>


3.9. példa - Korlátozó adattípus-tulajdonság nem megengedett alkalmazása

Tekintsük az alábbi típusdefiníciókat:

<xs:simpleType name="baseString">
    <xs:restriction base="xs:string">
        <xs:minLength value="1"/>
        <xs:maxLength value="256"/>
    </xs:restriction>
</xs:simpleType>

<xs:simpleType name="illegalString">
    <xs:restriction base="baseString">
        <xs:minLength value="0"/>
        <xs:maxLength value="100"/>
    </xs:restriction>
</xs:simpleType>

<xs:simpleType name="fixedLengthString">
    <xs:restriction base="baseString">
        <xs:length value="10"/>
    </xs:restriction>
</xs:simpleType>

A string beépített adattípusból megszorítással származtatott baseString adattípus értékterét a legalább 1 és legfeljebb 256 karaktert tartalmazó karakterláncok alkotják. Az illegalString nevű típusdefiníció nem megengedett, mivel a minLength korlátozó adattípus-tulajdonság értéke kisebb, mint az alap-típusdefiníció minLength korlátozó adattípus-tulajdonságának értéke, amely az alaptípus értékterénél bővebb értékteret eredményezne. Ugyanakkor a fixedLengthString nevű típusdefiníció megengedett, mivel a length korlátozó adattípus-tulajdonság értéke az alaptípus értékterét szűkíti.


Adattípusok származtatása listaképzéssel

Típusdefiníció származtatása történhet egy elem-típusdefinícióból listaképzéssel, ekkor a típusdefiníciós simpleType elemben a list elemet kell megadni. Az elem-típusdefiníció kétféle, egymást kizáró módon jelezhető:

  • A list elem itemType tulajdonságának értékeként egy egyszerű típus-definíció neve adható meg.

  • A list elem gyermekeként megadható egy névtelen típusdefiníciós simpleType elem.

Az elemtípus kizárólag atomi vagy unió adattípus lehet, lista adattípus használata nem megengedett.

A simpleType elem a fentieknek megfelelő formáját a következőképpen foglalhatjuk össze (a felső szintű típusdefiníciót adjuk meg, névtelen típusdefinícióban el kell hagyni a name tulajdonságot):

<simpleType name="név">
    <xs:list itemType="elemtípus"/>  (felső színtű típusdefiníció használata)
</simpleType>

<simpleType name="név">
    <xs:list>
        <xs:simpleType>  (névtelen típusdefiníció használata)
            ...
        </xs:simpleType>
    </xs:list>
</simpleType>
                    

3.10. példa - Lista adattípus definíciója

Az alábbi LotteryNumberList lista adattípus definíciójában a LotteryNumber felhasználói adattípust használjuk elemtípusként, értékterét tetszőleges számú LotteryNumber típusú értékből álló listák alkotják. A WinningNumberList lista adattípust megszorítással származtatjuk a LotteryNumberList lista adattípusból, az elemek számaként ötöt előírva.

A LotteryNumberList típusú LotteryNumbers elemben tetszőleges számú, whitespace karakterekkel elválasztott 1 és 90 közötti egész számot ábrázoló integer literál megengedett, míg a WinningNumberList típusú WinningNumbers elemben pontosan öt ilyen literál kötelező.

<xs:simpleType name="LotteryNumber">
    <xs:restriction base="xs:integer">
        <xs:minInclusive value="1"/>
        <xs:maxInclusive value="90"/>
    </xs:restriction>
</xs:simpleType>

<xs:simpleType name="LotteryNumberList">
    <xs:list itemType="LotteryNumber"/>
</xs:simpleType>

<xs:simpleType name="WinningNumberList">
    <xs:restriction base="LotteryNumberList">
        <xs:length value="5"/>
    </xs:restriction>
</xs:simpleType>

<xs:element name="LotteryNumbers" type="LotteryNumberList"/>

<xs:element name="WinningNumbers" type="WinningNumberList"/>
                        

Érvényesek például a LotteryNumbers elem következő előfordulásai:

<LotteryNumbers/>
<LotteryNumbers>42</LotteryNumbers>
<LotteryNumbers>40
    54 73</LotteryNumbers>
<LotteryNumbers>13 13 13 13</LotteryNumbers>

Megjegyezzük, hogy a WinningNumberList lista adattípus az alábbi módon is származtatható:

<xs:simpleType name="WinningNumberList">
    <xs:restriction>
        <xs:simpleType>
            <xs:list itemType="LotteryNumber"/>
        </xs:simpleType>
        <xs:length value="5"/>
    </xs:restriction>
</xs:simpleType>

[Megjegyzés]Megjegyzés

Az XML Schema nem teszi lehetővé olyan követelmény kifejezését, hogy a LotteryNumbers és WinningNumbers elemekben megjelenő literálok különböző értékeket kell hogy ábrázoljanak.


[Fontos]Fontos

Elemtípusként előfordulhat olyan adattípus, amelynek lexikális tere megengedi a whitespace karaktereket a literálokban, mint például a string adattípus. Ilyen adattípusok használata elemtípusként azért problémás, mert a lista adattípusok literáljaiban a whitespace karakterek az elemeket választják el.

3.11. példa - A string adattípus, mint elemtípus

Legyen adott a következő típusdefiníció:

<xs:simpleType name="stringList">
    <xs:list itemType="xs:string"/>
</xs:simpleType>

Például a [first item],[second item] literál egy olyan háromelemű listát ábrázol, amelynek elemei a következő karakterláncok:

[first
item],[second
item]


Adattípusok származtatása unióképzéssel

Típusdefiníció származtatása történhet egy vagy több tag-típusdefinícióból unióképzéssel, ekkor a típusdefiníciós simpleType elemben a union elemet kell megadni. A tag-típusdefiníciókat kétféle módon is fel lehet sorolni, az alábbi két megoldás akár együtt is használható:

  • A union elem memberTypes tulajdonságának értékeként a tagtípusok neveinek listája adható meg.

  • A union elem gyermekeként megadható tetszőleges számú típusdefiníciós simpleType elem.

Legalább egy tag-típusdefiníció kötelező. Tagtípusként használható atomi, lista és unió adattípus egyaránt.

3.12. példa - Unió adattípus definíciója

Az alábbi módon definiált unió adattípus értéktere a beépített date és gYear adattípusok értékterének halmazelméleti uniója:

<xs:simpleType name="dateOrYear">
    <xs:union memberTypes="xs:date xs:gYear"/>
</xs:simpleType>


3.13. példa - Unió adattípus definíciója

Az alábbi módon definiált unió adattípus értékterét a kettő és tíz közötti (integer típusú) egész számok alkotják a (token típusú) Jack, Queen, King és Ace karakterláncokkal együtt:

<xs:simpleType name="CardValue">
    <xs:union>
        <xs:simpleType>
            <xs:restriction base="xs:integer">
                <xs:minInclusive value="2"/>
                <xs:maxInclusive value="10"/>
            </xs:restriction>
        </xs:simpleType>
        <xs:simpleType>
            <xs:restriction base="xs:token">
                <xs:enumeration value="Jack"/>
                <xs:enumeration value="Queen"/>
                <xs:enumeration value="King"/>
                <xs:enumeration value="Ace"/>
            </xs:restriction>
        </xs:simpleType>
    </xs:union>
</xs:simpleType>


3.14. példa - Unió adattípus definíciója

Az alábbi isbn adattípus értéktere az isbn10 és isbn13 felhasználói adattípusok halmazelméleti uniója:

<xs:simpleType name="isbn10">
    <xs:restriction base="xs:string">
        <xs:pattern value="\d{9}[\dX]"/>
    </xs:restriction>
</xs:simpleType>

<xs:simpleType name="isbn13">
    <xs:restriction base="xs:string">
        <xs:pattern value="\d{13}"/>
    </xs:restriction>
</xs:simpleType>

<xs:simpleType name="isbn">
    <xs:union memberTypes="isbn10 isbn13"/>
</xs:simpleType>


[Megjegyzés]Megjegyzés

Típusdefinícióban lényeges a tag-típusdefiníciók felsorolásának sorrendje. Előfordulhat ugyanis, hogy az unió adattípus egy literálja több tagtípus literálja is. Egy ilyen literál típusa az érvényesítés során a sorrendben első olyan tagtípus, amelynek érvényes literálja. Elemek esetében a példányokban ez felülbírálható az xsi:type tulajdonság megadásával, amelynek értéke szolgáltatja az érvényesítéshez használandó tagtípus nevét.

3.15. példa - Tag-típusdefiníciók sorrendje unió adattípus definíciójában

Legyenek adottak a következő sémakomponensek:

<xs:simpleType name="decimalOrString">
    <xs:union memberTypes="xs:decimal xs:string"/>
</xs:simpleType>

<xs:element name="value" type="decimalOrString"/>

A value elem érvényes előfordulásai például az alábbiak:

<value>42</value>       a literál decimal típusú
<value>5.0</value>      a literál decimal típusú
<value>Hungary</value>  a literál string típusú
<value>2.13.1</value>   a literál string típusú
<value xsi:type="xs:string">1</value>   a literál string típusú


Származtatás korlátozása

Felső szintű típusdefiníciókban a simpleType elemekhez megadható final tulajdonság révén korlátozható a típusdefiníció származtatáshoz történő felhasználása, lehetséges értékei és jelentéseik:

restriction

Azt jelenti, hogy nem származtatható a típusdefinícióból megszorítással új típusdefiníció.

list

Azt jelenti, hogy nem megengedett a típusdefiníció listaképzéshez elem-típusdefinícióként való használata.

union

Azt jelenti, hogy nem megengedett a típusdefiníció unióképzéshez tag-típusdefinícióként való használata.

#all

Azt jelenti, hogy semmilyen módon sem származtatható a típusdefinícióból új típusdefiníció.

Megjegyezzük, hogy egy további opció a final tulajdonság értékeként egy, a restriction, list és union értékekből képzett lista megadása. Például list union azt jelenti, hogy nem megengedett a típusdefiníció unióképzéshez tag-típusdefinícióként és listaképzéshez elem-típusdefinícióként való használata, azonban megszorítással származtatható a típusdefinícióból új típusdefiníció.

3.16. példa - Származtatás korlátozása

Az alábbi típusdefinícióból semmilyen módon sem származtatható új típusdefiníció:

<xs:simpleType name="shortString" final="#all">
    <xs:restriction base="xs:string">
        <xs:maxLength value="10"/>
    </xs:restriction>
</xs:simpleType>


A származtatás korlátozásának egy másik módja a korlátozó adattípus-tulajdonságok értékeinek rögzítése. Opcionálisan adható meg a korlátozó adattípus-tulajdonságokat ábrázoló elemekhez a logikai értékű fixed tulajdonság, amelynek alapértelmezett értéke false. Ha a tulajdonság értéke true egy korlátozó adattípus-tulajdonság esetén, akkor a típusdefinícióból megszorítással történő származtatás során az adott korlátozó adattípus-tulajdonság értékeként csak az alap-típusdefinícióban meghatározott érték fordulhat elő. Megjegyezzük, hogy az enumeration és pattern korlátozó adattípus-tulajdonságokhoz nem áll rendelkezésre a fixed tulajdonság.

3.17. példa - Korlátozó adattípus-tulajdonság értékének rögzítése

Az alábbi típusdefinícióból származtatható megszorítással típusdefiníció, azonban származtatás során a minInclusive adattípus-tulajdonság értékeként csak 0, a maxInclusive adattípus-tulajdonság értékeként pedig csak 1 megengedett:

<xs:simpleType name="unitIntervalValue">
    <xs:restriction base="xs:decimal">
        <xs:minInclusive value="0" fixed="true"/>
        <xs:maxInclusive value="1" fixed="true"/>
    </xs:restriction>
</xs:simpleType>

Érvényes például a következő származtatás:

<xs:simpleType>
    <xs:restriction base="unitIntervalValue">
        <xs:fractionDigits value="2"/>
        <xs:maxInclusive value="1"/>
    </xs:restriction>
</xs:simpleType>

Vegyük észre, hogy az utóbbi típusdefinícióban egyébként feleslegesen szerepeltetjük a maxInclusive adattípus-tulajdonságot.


Az anySimpleType adattípus

Az anySimpleType adattípus valamennyi beépített primitív adattípus alaptípusa. Értéktere a beépített primitív adattípusok értéktereinek valamint a beépített primitív adattípusok értékeiből alkotható listák halmazának uniója. A lexikális térre nem vonatkoznak korlátozások.

4. fejezet - Komplex típusok

Bevezetés

Az előző fejezetben tárgyalt egyszerű típusok elemekhez és tulajdonságokhoz egyaránt felhasználhatóak. A komplex típusok tulajdonságok és tartalomként elemek használatát teszik lehetővé, ezért természetszerűleg csak elemekhez állnak rendelkezésre.

Komplex típusok szükségesek

  • csak elemeket tartalmazó elemekhez,

  • szöveget és elemeket is tartalmazó (vegyes tartalmú) elemekhez,

  • tulajdonságokkal rendelkező elemekhez,

  • speciálisan az olyan üres elemekhez, amelyekenek nincs tartalma és tulajdonságai sincsenek.

Ez a fejezet a komplex típusok használatát tárgyalja részletesen. Példákkal szemléltetve mutatjuk be a komplex típusok definiálásának valamennyi lehetséges módját. A szemléletesség kedvéért a példákban a típusdefiníciókat általában azokat felhasználó elemdeklarációkkal együtt adjuk meg.

Komplex típusok definiálása

Komplex típusok definiálására egy olyan sémakomponens szolgál, amelyeket a sémadokumentomokban a complexType elem ábrázol. A sémában két helyen helyezhető el típusdefiníció:

  • Felső szinten, azaz közvetlenül a schema elem gyermekeként megjelenő típusdefinícióban kötelező egy név megadása a name tulajdonság értékeként, amely a sémában a típusdefiníciót egyedi módon azonosítja. A név lehetővé teszi a típusra történő hivatkozást.

  • Elemdeklaráció részeként is megjelenhet komplex típus definíciója, amelyhez tilos név megadása. Ilyenkor névtelen típusdefinícióról beszélünk, a megfelelő típust pedig névtelen típusnak nevezzük. A névtelen típusok felhasználása a típusdefiníció helyén történik.

Megjegyezzük, hogy az egyszerű és komplex típusok nevei különbözőek kell, hogy legyenek minden sémában.

4.1. példa - Nevesített komplex típus definíciója és felhasználása

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:complexType name="event">
        <xs:sequence>
            <xs:element name="date" type="xs:date"/>
            <xs:element name="place" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>

    <xs:element name="birth" type="event"/>
    <xs:element name="event" type="event"/>
    ...
</xs:schema>

4.2. példa - Névtelen komplex típus definíciója és felhasználása

<xs:element name="param">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="name" type="xs:string"/>
            <xs:element name="value" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>

Minden komplex típus definíciója meghatároz egy tartalomtípust, amely alapján elvégezhető azon elemeknek tartalmának érvényesítése, amelyek típusaként az adott típust felhasználjuk. Minden komplex típus definíciója meghatározhatja továbbá tulajdonságok használatának módját, amely szintén felhasználásra kerül az érvényesítéshez. A típusdefinícióban a típus néhány további jellemzője is megadható.

Csak elemeket tartalmazó elemek

Ebben a szakaszban a típusdefiníciók azon fajtáját tárgyaljuk, amelyek elemekben gyermekként csak elemeket engednek meg, és nem teszik lehetővé tulajdonságok használatát sem. Az ilyen típusdefiníciók legegyszerűbb formája:

<xs:complexType name="név">    (felső szintű típusdefiníció)
    tartalommodellt megadó elem
</xs:complexType>

<xs:complexType>               (névtelen típusdefiníció)
    tartalommodellt megadó elem
</xs:complexType>

A fenti szintaxis valójában a teljes szintaxis egy rövidítése, amelyet a Komplex típus definíciójának megszorítása című szakaszban mutatunk be. A complexType elemben egyetlen, a tartalommodellt meghatározó elemet kell elhelyezni, amely lehet:

Mindkét lehetőségnek egy külön szakaszt szentelünk.

Tartalommodellek

Az XML 1.0 tartalommodellnek nevezi azokat a kifejezéseket, amelyeket az olyan elemek deklarációiban használunk a megengedett tartalom meghatározására, amelyekben gyermekként csak elemek fordulhatnak elő. Egy tartalommodell például az

<!ELEMENT d (a?,(b|c)+)*>

DTD elemtípus-deklarációban az (a?,(b|c)+)* kifejezés. Egy tartalommodell meghatározza a gyermekként megengedett elemek nevét és sorrendjét.

Az XML séma a DTD-hez hasonlóan teszi lehetővé komplex típusok definícióihoz a tartalommodellek leírását. Az alább bemutatásra kerülő konstrukciók segítségével kifejezhető a DTD összes lehetséges tartalommodellje.

Míg a tartalommodelleket a DTD-ben a reguláris kifejezésekéhez hasonló szintaxis ábrázolja, addig az XML Schema elemeket használ a tartalmodellek leírására. A DTD tartalommodell szintaxisa tömörebbnek és jobban olvashatónak tűnhet, használata mégis nagyon kényelmetlen lehet olyan esetekben, amelyekben ugyanakkor az XML Schema egyszerű megoldást kínál.

4.3. példa - Tartalommodell kifejezése DTD-ben és sémában

Egy olyan tartalommodellre adunk példát, amelynek kifejezése a DTD-ben nagyon körülményes, míg az XML Schema esetében kézenfekvő. Deklaráljunk egy olyan d elemet, amely pontosan egy a, b és c elemet tartalmazhat tetszőleges sorrendben!

DTD-ben ez alábbi módon tehető meg:

<!ELEMENT d ((a,b,c)|(a,c,b)|(b,a,c)|(b,c,a)|(c,a,b)|(c,b,a))>

A deklarációban alternatívaként kell felsorolnunk az elemek összes lehetséges sorrendjét, ez roppant kényelmetlen és sok hibaforrást rejt magában.

Az XML Schema megoldása:

<xs:element name="d">
    <xs:complexType>
        <xs:all>
            <xs:element ref="a"/>
            <xs:element ref="b"/>
            <xs:element ref="c"/>
        </xs:all>
    </xs:complexType>
</xs:element>

Tetszőleges elemsorrend kifejezésére szolgál a fenti típusdefinícióban látható, modellcsoportnak nevezett all elem.


Modellcsoportok

Modellcsoportoknak nevezzük az XML Schema alábbi, tartalommodellek kifejezésére szolgáló konstrukcióit:

  • sequence

  • choice

  • all

Minden modellcsoportot egy azonos nevű elem ábrázol az XML Schema névtérben. Mindhárom esetben megadható

  • az előfordulások minimális száma a minOccurs tulajdonsággal,

  • az előfordulások maximális száma a maxOccurs tulajdonsággal.

A két tulajdonság alapértelmezett értéke mind a három modellcsoport esetén 1, azonban lehetséges értékeik eltérőek.

Tartalommodellek leírásához minden egyes modellcsoportban az alábbiak közül bizonyosak adhatóak meg tetszőleges számban és sorrendben:

  • sequence és choice modellcsoport (azonban all modellcsoport nem),

  • any helyettesítő,

  • lokális elemdeklaráció,

  • globális elemdeklarációra történő hivatkozás,

  • modellcsoport-definícióra történő hivatkozás (lásd a Modellcsoport-definíciók című szakaszt).

A tartalommodellek fenti alkotóelemeit részecskéknek nevezzük. Megjegyezzük, hogy a modellcsoportoknál részben eltérő korlátozások vonatkoznak a részecskék használatára (az all modellcsoport sokkal korlátozottabb módon használható, mint a sequence és a choice).

Egy-egy szakasz mutatja be az egyes modellcsoportokat. Látni fogjuk, hogy a modellcsoportok egymásba ágyazhatósága révén tetszőlegesen összetett tartalommodelleket ki lehet fejezni.

A sequence modellcsoport

A sequence modellcsoport egy kötött sorrend határoz meg, a részecskéket az előfordulásuk sorrendjében kell a tartalom érvényesítéséhez használni. A modellcsoportban mindegyik potenciális részecske szerepelhet. A minOccurs tulajdonság értékeként tetszőleges nemnegatív egész megengedett, a maxOccurs tulajdonság értéke pedig tetszőleges nemnegatív egész lehet, valamint az unbounded karakterlánc.

4.4. példa - A sequence modellcsoport használata

Tekintsük az alábbi elemdeklarációt:

<xs:element name="file">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="uri" type="xs:anyURI"/>
            <xs:element name="description" type="xs:string" minOccurs="0"/>
            <xs:element name="size" type="xs:nonNegativeInteger"/>
            <xs:element name="contentType" type="xs:string"/>
            <xs:element name="lastModified" type="xs:dateTime" minOccurs="0"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>

A file elemben a következő elemek megengedettek ebben a sorrendben: pontosan egy uri elem, egy opcionális description elem, pontosan egy size és contentType, végül egy opcionális lastModified elem. Érvényesek például a file elem következő előfordulásai:

<file>
    <uri>http://www.apache.org/dist/ant/binaries/apache-ant-1.8.2-bin.zip</uri>
    <size>10920710</size>
    <contentType>application/zip</contentType>
    <lastModified>2010-12-20T18:47Z</lastModified>
</file>

<file>
    <uri>http://spaceflight.nasa.gov/gallery/images/apollo/apollo11/hires/as11_40_5903.jpg</uri>
    <description>Astronaut Edwin Aldrin, Jr.</description>
    <size>3101893</size>
    <contentType>image/jpeg</contentType>
</file>


4.5. példa - A sequence modellcsoport használata

A sequence modellcsoporthoz pontosan úgy használhatjuk a minOccurs és maxOccurs tulajdonságokat az előfordulások számának előírására, mint a lokális elemdeklarációkhoz. Tekintsük például az alábbi elemdeklarációt:

<xs:element name="data">
    <xs:complexType>
        <xs:sequence minOccurs="0" maxOccurs="unbounded">
            <xs:element ref="block"/>
            <xs:element ref="checksum"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>

A data elemben tetszőleges számban fordulhatnak elő egymást követő block és checksum elemek. A minOccurs tulajdonság értéke miatt a data elem lehet üres is.


A choice modellcsoport

A choice modellcsoport alternatívák egy csoportját reprezentálja. A sequence modellcsoporthoz hasonlóan valamennyi részecske megengedett benne, amelyeknek azonban nem számít a sorrendje. Tartalom érvényesítéséhez a részecskék egyike kerül felhasználásra. A minOccurs tulajdonság értékeként tetszőleges nemnegatív egész megengedett, a maxOccurs tulajdonság értéke pedig tetszőleges nemnegatív egész lehet, valamint az unbounded karakterlánc.

4.6. példa - A choice modellcsoport használata

Tekintsük az alábbi elemdeklarációt:

<xs:element name="value">
    <xs:complexType>
        <xs:choice>
            <xs:element name="float" type="xs:float"/>
            <xs:element name="int" type="xs:int"/>
            <xs:element name="string" type="xs:string"/>
        </xs:choice>
    </xs:complexType>
</xs:element>

A value elemben pontosan egy float, int vagy string elem kötelező. Érvényesek például a value elem alábbi előfordulásai:

<value><float>1E-5</float></value>
<value><int>1024</int></value>
<value><string>C-3PO</string></value>


4.7. példa - A choice modellcsoport használata

Tekintsük az alábbi elemdeklarációt:

<xs:element name="array">
    <xs:complexType>
        <xs:choice>
            <xs:element name="float" type="xs:float" maxOccurs="unbounded"/>
            <xs:element name="int" type="xs:int" maxOccurs="unbounded"/>
            <xs:element name="string" type="xs:string" maxOccurs="unbounded"/>
        </xs:choice>
    </xs:complexType>
</xs:element>

Az array elemben a float, int vagy string elemek valamelyike kötelező legalább egyszer. Érvényes például az alábbi:

<array>
    <string>George</string>
    <string>John</string>
    <string>Paul</string>
    <string>Ringo</string>
</array>


4.8. példa - A choice modellcsoport használata

Tekintsük az alábbi elemdeklarációt:

<xs:element name="array">
    <xs:complexType>
        <xs:choice maxOccurs="unbounded">
            <xs:element name="float" type="xs:float"/>
            <xs:element name="int" type="xs:int"/>
            <xs:element name="string" type="xs:string"/>
        </xs:choice>
    </xs:complexType>
</xs:element>

A fenti típusdefiníció annyiban tér el a 4.6. példa - A choice modellcsoport használata típusdefiníciójától, hogy a choice elemhez az unbounded értékkel adtuk meg a maxOccurs tulajdonságot. Így az array elemben a float, int és string elemek tetszőleges számban és sorrendben fordulhatnak elő, de legalább egy elem kötelező. Érvényes például az alábbi:

<array>
    <string>Mace Windu</string>
    <int>42</int>
    <string>Obi-Wan Kenobi</string>
    <float>123.0</float>
    <string>Qui-Gon Jinn</string>
</array>


Az all modellcsoport

Az all modellcsoportban részecskeként olyan lokális elemdeklarációk és globális elemdeklarációkra történő hivatkozások megengedettek csak, ahol a minOccurs és maxOccurs tulajdonságok értéke 0 vagy 1. A modellcsoport jelentése az, hogy az adott elemek tetszőleges sorrendben fordulhatnak elő. Egy további korlátozás, hogy az all elemhez tartozó minOccurs és maxOccurs tulajdonságok értékeként nem adható meg az alapértelmezéstől eltérő érték (az alapértelmezés 1). A sequence és choice modellcsoport sem tartalmazhatja az all modellcsoportot, amely így csak a legfelső szinten jelenhet meg tartalommodell leírásánál.

4.9. példa - Az all modellcsoport használata

Tekintsük az alábbi elemdeklarációt:

<xs:element name="address">
    <xs:complexType>
        <xs:all>
            <xs:element name="street" type="xs:string"/>
            <xs:element name="city" type="xs:string"/>
            <xs:element name="state" type="xs:string" minOccurs="0" maxOccurs="1"/>
            <xs:element name="postalCode" type="xs:string"/>
            <xs:element name="country" type="xs:string"/>
        </xs:all>
	</xs:complexType>
</xs:element>

Az address elemben pontosan egy street, city, postalCode és country elem kötelező, megengedett továbbá egy opcionális state elem. Ezek az elemek tetszőleges sorrendben fordulhatnak elő. Érvényesek például az alábbiak:

<address>
    <city>Debrecen</city>
    <street>Egyetem tér 1.</street>
    <postalCode>4032</postalCode>
    <country>Hungary</country>
</address>

<address>	
    <street>456 Kent Street</street>
    <city>Sydney</city>
    <state>NSW</state>
    <postalCode>2000</postalCode>
    <country>Australia</country>
</address>


Modellcsoportokra vonatkozó korlátozások

Ha egy modellcsoport azonos nevű elemdeklarációkat tartalmaz részecskeként közvetlenül vagy közvetett módon, akkor az azonos nevű deklarációkhoz ugyanaz a felső szintű (névvel rendelkező) típusdefiníció kell hogy tartozzon. A közvetlen tartalmazás az elemgyermekként való tartalmazást jelenti. A közvetett tartalmazás pedig azt, hogy a deklarációt egy, a modellcsoportban elemgyermekként előforduló vagy hivatkozott sequence vagy choice modellcsoport tartalmazza közvetlenül vagy közvetett módon.

4.10. példa - Nem megengedett modellcsoport

Nem megengedett például az alábbi három modellcsoport, mert a részecskeként felhasznált azonos nevű elemek különböző típusúak:

<xs:choice>
    <xs:element name="value" type="xs:int"/>
    <xs:element name="value" type="xs:string"/>
</xs:choice>

<xs:sequence>
    <xs:element name="value" type="xs:int"/> 
    <xs:element name="value" type="xs:string"/>
</xs:sequence>

<xs:sequence>
    <xs:choice>
        <xs:element name="value1" type="xs:int"/>
        <xs:element name="value2" type="xs:string"/>
    </xs:choice> 
    <xs:element name="value1" type="xs:string"/>
</xs:sequence>

[Megjegyzés]Megjegyzés

Az első modellcsoport kiváltható az alábbi elemdeklarációval, amely a value elemben tartalomként megengedi az int és string adattípus literáljait is:

<xs:element name="value">
    <xs:simpleType>
        <xs:union memberTypes="xs:int xs:string"/>
    </xs:simpleType>
</xs:element>


Egy további korlátozás, hogy minden modellcsoport egyértelmű kell, hogy legyen a következő értelemben. Ha egy modellcsoportot érvényesítéshez kell felhasználni, akkor minden egyes elem egyértelműen megfeleltethető kell, hogy legyen a modellcsoportban közvetlenül vagy közvetett módon tartalmazott valamely részecskének úgy, hogy ehhez nem használhatóak fel az elem tartalma és tulajdonságai, sem a dokumentumban ezt követő elemek.

4.11. példa - Nem egyértelmű modellcsoport

Nem egyértelmű például az alábbi modellcsoport:

<xs:sequence>
    <xs:choice>
        <xs:element ref="A"/>
        <xs:element ref="B" minOccurs="0"/>
    </xs:choice>
    <xs:choice>
        <xs:element ref="A"/>
        <xs:element ref="C"/>
    </xs:choice>
</xs:sequence>

Ugyanis ha egy olyan A elemet olvasunk be, amelynek érvényesítéséhez a fenti modellcsoportot kell használni, akkor az elem megfeleltethető mindkét choice elem első részecskéjének. Ha tudnánk, hogy az A elem után mi következik a dokumentumban, akkor egyértelmű lenne, hogy melyik choice modellcsoportnak felel meg a bemenet. Ez az információ azonban nem áll rendelkezésre, mivel még nem került beolvasásra a következő elem.

Egyértelmű azonban a következő modellcsoport:

<xs:sequence>
    <xs:choice>
        <xs:element ref="A"/>
        <xs:element ref="B"/>
    </xs:choice>
    <xs:choice>
        <xs:element ref="A"/>
        <xs:element ref="C"/>
    </xs:choice>
</xs:sequence>

Ugyancsak egyértelmű az alábbi:

<xs:sequence>
    <xs:choice>
        <xs:element ref="A"/>
        <xs:element ref="B"/>
    </xs:choice>
    <xs:choice>
        <xs:element ref="A" minOccurs="0"/>
        <xs:element ref="C"/>
    </xs:choice>
</xs:sequence>


Modellcsoportok kombinálása

Modellcsoport-definíciók

A modellcsoport-definíciók olyan másodlagos sémakomponensek, amelyek egy modellcsoport elnevezését teszik lehetővé többszöri felhasználás céljából. Az alábbi módon adható meg a schema elem gyermekeként egy modellcsoport-definíció:

<group name="név"> modellcsoport </group>

Az elemben tartalomként pontosan egy sequence, choice vagy all modellcsoport kötelező, amelyekhez nem adható meg sem a minOccurs, sem a maxOccurs tulajdonság.

Egy modellcsoport-definícióra a sequence és choice modellcsoportokban lehet hivatkozni az alábbi módon:

<group ref="név"/>

A hivatkozás a modellcsoport-definícióban tartalmazott modellcsoport felhasználást eredményezi a hivatkozás helyén. A hivatkozásban adható meg a modellcsoporthoz a minOccurs és maxOccurs tulajdonság.

4.12. példa - Modellcsoport-definíció

Legyen adott az alábbi modellcsoport-definíció:

<xs:group name="startAndEndDate">
    <xs:sequence>
        <xs:element name="startDate" type="xs:date"/>
        <xs:element name="endDate" type="xs:date"/>
    </xs:sequence>
</xs:group>

A definícióban szereplő csoportot például az alábbi módon használhatjuk fel egy komplex típus tartalommodelljéhez:

<xs:element name="event">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="title" type="xs:string"/>
            <xs:group ref="startAndEndDate"/>
            <xs:element name="location" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>

Az event elem egy lehetséges előfordulása:

<event>
    <title>XIX. Budapesti Nemzetközi Könyvfesztivál</title>
    <startDate>2012-04-19</startDate>
    <endDate>2011-04-22</endDate>
    <location>Budapest</location>
</event>


4.13. példa - Modellcsoport-definíció

A 4.8. példa - A choice modellcsoport használata típusdefiníciója modellcsoport-definícióval:

<xs:group name="floatOrIntOrString">
    <xs:choice>
        <xs:element name="float" type="xs:float"/>
        <xs:element name="int" type="xs:int"/>
        <xs:element name="string" type="xs:string"/>
    </xs:choice>
</xs:group>

<xs:element name="array">
    <xs:complexType>
        <xs:group ref="floatOrIntOrString" minOccurs="1" maxOccurs="unbounded"/>
    </xs:complexType>
</xs:element>


Vegyes tartalmú elemek

A DTD lehetővé teszi olyan vegyes tartalmú elemek deklarálását, amelyek karakteres adatokat (szöveget) és elemeket is tartalmazhatnak gyermekként.

4.14. példa - Vegyes tartalmú elem deklarálása DTD-ben

Például a

<!ELEMENT para (#PCDATA|bold|italic)*>

módon deklarált para elem karakteres adatokat, valamint bold és italic elemeket tartalmazhat gyermekként tetszőleges számban és sorrendben.


Ez a lehetőséget természetesen az XML Schema is biztosítja. Vegyes tartalom előírásához a logikai típusú mixed tulajdonság áll rendelkezésre, amelyeket típusdefiníciókban a complexType elemekhez lehet megadni. Ha a tulajdonság értéke true, akkor a tartalommodell által megengedett elemgyermekek között tetszőlegesen helyezhető el szöveg.

4.15. példa - Vegyes tartalom használata

Tekintsük az alábbi elemdeklarációt:

<xs:element name="para">
    <xs:complexType mixed="true">
        <xs:choice minOccurs="0" maxOccurs="unbounded">
            <xs:element ref="bold"/>
            <xs:element ref="italic"/>
        </xs:choice>
    </xs:complexType>
</xs:element>

A para elem pontosan olyan módon használható a példányokban, mint a fenti DTD elemtípus-elemdeklarációban szereplő azonos nevű elem.


A DTD-hez képest az XML Schema sokkal rugalmasabban teszi lehetővé vegyes tartalom kezelését. Míg DTD esetén vegyes tartalmú elemekhez nem írható elő az elemgyermekek száma és sorrendje, XML sémák esetén tetszőleges tartalommodell megadható.

4.16. példa - Vegyes tartalom használata

Tekintsük az alábbi sémakomponenseket, amelyekkel egy levelek leírására szolgáló letter elemet deklarálunk:

<xs:element name="letter">
    <xs:complexType mixed="true">
        <xs:sequence>
            <xs:element name="salutation" type="mixedContent"/>
            <xs:element name="valediction" type="mixedContent"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>

<xs:complexType name="mixedContent" mixed="true">
    <xs:sequence>
        <xs:element name="name" type="xs:string"/>
    </xs:sequence>
</xs:complexType>

A letter elem egy olyan vegyes tartalmú elem, amelyben pontosan egy megszólítást tartalmazó salutation, utána pedig pontosan egy záradékot tartalmazó valediction elem megadása kötelező.

Vegyes tartalmúak a salutation és valediction elemek is, amelyekben pontosan egy name elem kötelező.

Érvényes például az alábbi elem:[4]

<letter>
    <salutation>Szeretve tisztelt <name>uram</name>,</salutation>
    üdvözlöm a Kárpátok peremén. Már igen várom. Aludjon jól az éjszaka.
    Holnap háromkor indul a delizsánsz Bukovinába. Helyet foglaltattam
    rajta. A Borgói-szorosban kocsim várni fogja és elhozza énhozzám.
    Remélem, jól utazott Londonból, és kellemesen tölti majd napjait az
    én kies vidékemen.
    <valediction>Szolgája
        <name>Drakula</name>
    </valediction>
</letter>


Tulajdonságok használata

Tulajdonságok használatára vonatkozó elemek a tartalommodellt meghatározó modellcsoport után adhatóak meg típusdefinícióban, amelyek mindegyike a következők valamelyike:

  • lokális tulajdonság-deklaráció,

  • globális tulajdonság-deklarációra történő hivatkozás,

  • tulajdonságcsoport-definícióra történő hivatkozás,

  • tulajdonság-helyettesítő.

A tulajdonság-helyettesítő kivételével a fentiek tetszőleges számban és sorrendben fordulhatnak elő, azonban adott nevű tulajdonság csak egyszer deklarálható. Kizárólag utolsóként és legfeljebb egyszer megengedett a Helyettesítők című szakasz részeként tárgyalt tulajdonság-helyettesítő.

4.17. példa - Tulajdonságok használata

Legyen adott az alábbi elemdeklaráció:

<xs:element name="bookmark">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="tag" type="xs:token" minOccurs="1" maxOccurs="unbounded"/>
        </xs:sequence>
        <xs:attribute name="uri" type="xs:anyURI" use="required"/>
        <xs:attribute name="title" type="xs:string" use="required"/>
    </xs:complexType>
</xs:element>

A fenti bookmark elemhez kötelezőként írtuk elő az uri és title tulajdonságok használatát. A bookmark elem egy lehetséges előfordulása:

<bookmark uri="http://www.porcupinetree.com/" title="Porcupine Tree - Official Website">
    <tag>progressive</tag>
    <tag>rock</tag>
    <tag>metal</tag>
    <tag>music</tag>
    <tag>band</tag>
</bookmark>


Szövegtartalmú elemek tulajdonságokkal

Komplex típusú minden olyan elem, amelyhez megengedett tulajdonságok használata. Egy egyszerű típus definíciójának kiterjesztésével alkotható olyan típusdefiníció, amely tartalomként csak az alaptípus literáljait engedi meg. A kiterjesztés formája a következő (a felő szintű típusdefiníciót adjuk meg, névtelen típusdefinícióban el kell hagyni a name tulajdonságot):

<xs:complexType name="név">
    <xs:simpleContent>
        <xs:extension base="alaptípus">
            tulajdonságok használatára vonatkozó elemek
        </xs:extension>
    </xs:simpleContent>
</xs:complexType>

4.18. példa - Tulajdonsággal rendelkező szövegtartalmú elem használata

Az alábbi módon deklarált image elem tartalmaként az anyURI típus literáljai megengedettek, opcionálisan adható meg az xs:nonNegativeInteger típusú width és height tulajdonság:

<xs:element name="image">
    <xs:complexType>
        <xs:simpleContent>
            <xs:extension base="xs:anyURI">
                <xs:attribute name="width" type="xs:nonNegativeInteger" use="optional"/>
                <xs:attribute name="height" type="xs:nonNegativeInteger" use="optional"/>
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>
</xs:element>

Az elem egy lehetséges előfordulása például:

<image width="72" height="48">http://www.w3.org/Icons/w3c_home.png</image>


4.19. példa - Tulajdonsággal rendelkező szövegtartalmú elem használata

Tekintsük az alábbi sémakomponenseket:

<xs:simpleType name="myDecimal">
    <xs:restriction base="xs:decimal">
        <xs:minInclusive value="0"/>
        <xs:fractionDigits value="2"/>
    </xs:restriction>
</xs:simpleType>

<xs:element name="price">
    <xs:complexType>
        <xs:simpleContent>
            <xs:extension base="myDecimal">
                <xs:attribute name="currency" use="optional" default="EUR">
                    <xs:simpleType>
                        <xs:restriction base="xs:token">
                            <xs:enumeration value="CHF"/>
                            <xs:enumeration value="EUR"/>
                            <xs:enumeration value="USD"/>
                        </xs:restriction>
                    </xs:simpleType>    
                </xs:attribute>
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>
</xs:element>

A price elem típusa egy olyan névtelen komplex típus, amely tartalomként egy myDecimal típusú literált követel meg és lehetővé teszi az opcionális currency tulajdonság megadásást.


Üreselemek

Komplex típusdefiníció szükséges az üreselemekhez, amelyeknek nincs tartalmuk. Üreselem típusdefiníciójaként olyan complexType elemet kell használni, amely nem határoz meg tartalommodellt. Tulajdonságai lehetnek az üreselemeknek is, ezeket a szokásos módon adhatjuk meg. Ha az üreselemnek tulajdonságai sincsenek, akkor a complexType elem üres.

4.20. példa - Üreselem deklarálása

Az alábbi módon deklarálhatunk egy olyan point üreselemet, amelyhez kötelező az x és y tulajdonságok megadása:

<xs:element name="point">
    <xs:complexType>
        <xs:attribute name="x" type="xs:double" use="required"/>
        <xs:attribute name="y" type="xs:double" use="required"/>
    </xs:complexType>
</xs:element>

Példa a point elem egy előfordulására:

<point x="-0.459372" y="0.046004"/>


4.21. példa - Üreselem deklarálása

Alább egy olyan newline üreselemet deklarálunk, amelyhez tulajdonságok sem adhatók meg:

<xs:element name="newline">
    <xs:complexType/>
</xs:element>

Példa az elem előfordulására:

<newline/>


Komplex típusok megszorítása és kiterjesztése

Komplex típus definíciójának kiterjesztése

Egy komplex típus definíciója lehet egy másik komplex típus definíciójának kiterjesztése. A kiterjesztés révén származtatott új típus megörökli az alaptípus tartalommodelljét és tulajdonságait, amelyeket bővíthet. A kiterjesztés módja az alábbi (a felső szintű típusdefiníciót adjuk meg, névtelen típusdefinícióban el kell hagyni a name tulajdonságot):

<xs:complexType name="név">
    <xs:complexContent>
        <xs:extension base="alaptípus">
            tartalommodellt megadó elem
            tulajdonságok használatára vonatkozó elemek
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

A származtatott típus tartalommodellje egy olyan sequence modellcsoportként tekinthető, amelyben az alaptípus tartalommodelljét az extension elemben megadott tartalommodell követi. Természetesen az eredményül kapott tartalommodellre is kell, hogy teljesüljenek a modellcsoportokra vonatkozó korlátozások. A származtatott típushoz csak olyan tulajdonságok adhatóak meg, amelyek nevei különböznek az alaptípus tulajdonságainak neveitől.

4.22. példa - Komplex típus kiterjesztése

Tekintsük az alábbi sémakomponenseket:

<xs:complexType name="eventType">
    <xs:sequence>
            <xs:element name="date" type="xs:date"/>
            <xs:element name="place" type="xs:string"/>
    </xs:sequence>
</xs:complexType>

<xs:element name="birth" type="eventType"/>

<xs:element name="death">
    <xs:complexType>
        <xs:complexContent>
            <xs:extension base="eventType">
                <xs:sequence>
                    <xs:element name="cause" type="xs:string" minOccurs="0"/>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
</xs:element>

<xs:element name="person">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="name" type="xs:string"/>
            <xs:element ref="birth"/>
            <xs:element ref="death" minOccurs="0"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>

A person elem egy lehetséges előfordulása:

<person>
    <name>John F. Kennedy</name>
    <birth>
        <date>1917-05-29</date>
        <place>Brookline, Massachusetts, U.S.</place>
    </birth>
    <death>
        <date>1963-11-22</date>
        <place>Dallas, Texas, U.S.</place>
        <cause>assassination</cause>
    </death>
</person>

Az eventType komplex típust esemény-jellegű információk ábrázolásához definiáltuk, amely tartalomként egy dátumot (date elem) és egy helyet (place elem) követel meg. A person elemben a születési adatokat tartalmazó birth elemhez használjuk fel az eventType típust.

A halál idejét, helyét és okát tartalmazó opcionális death elemhez egy olyan névtelen típusdefiníciót adunk meg, amelyben az eventType típus definícióját terjesztjük ki, tartalommodelljét egy opcionális elemmel bővítve. Az új típus tartalommodelljét a

<xs:sequence>
    <xs:sequence>
        <xs:element name="date" type="xs:date"/>
        <xs:element name="place" type="xs:string"/>
    </xs:sequence>
    <xs:sequence>
        <xs:element name="cause" type="xs:string" minOccurs="0"/>
    </xs:sequence>
</xs:sequence>

modellcsoport írja le.


4.23. példa - Komplex típus kiterjesztése

Tekintsük az alábbi sémakomponenseket:

<xs:complexType name="CelestialObjectType">
    <xs:sequence>
        <xs:element name="mass" type="xs:double"/>
    </xs:sequence>
    <xs:attribute name="id" type="xs:ID" use="required"/>
</xs:complexType>

<xs:complexType name="PlanetType">
    <xs:complexContent>
        <xs:extension base="CelestialObjectType">
            <xs:sequence>
                <xs:element name="hasMoon" minOccurs="0" maxOccurs="unbounded">
                    <xs:complexType>
                        <xs:attribute name="ref" type="xs:IDREF" use="required"/>
                   </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

<xs:element name="SolarSystem">
    <xs:complexType>
        <xs:sequence>
            <xs:element ref="CelestialObject" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>

<xs:element name="CelestialObject" type="CelestialObjectType"/>

<xs:element name="Planet" type="PlanetType" substitutionGroup="CelestialObject"/>

A SolarSystem elem egy lehetséges előfordulása:

<SolarSystem>

    <Planet id="MARS">
        <mass>6.421e+23</mass>
        <hasMoon ref="PHOBOS"/>
        <hasMoon ref="DEIMOS"/>
    </Planet>

    <CelestialObject id="PHOBOS">
        <mass>1.08e+16</mass>
    </CelestialObject>

    <CelestialObject id="DEIMOS">
        <mass>1.80e+15</mass>
    </CelestialObject>

</SolarSystem>

Csillagászati objektumok leírásához alkottuk meg a CelestialObjectType típusú CelestialObject elemet. A tömörség kedvéért az objektumokhoz csak az azonosítójukat (id tulajdonság) és tömegüket (mass elem) adjuk meg.


Komplex típus definíciójának megszorítása

Egy komplex típus definíciója lehet egy másik komplex típus definíciójának megszorítása. A megszorítás révén az alaptípus tartalommodellje és tulajdonságainak használata korlátozható. A megszorítást az alábbi formában kell megadni (a felső szintű típusdefiníciót adjuk meg, névtelen típusdefinícióban el kell hagyni a name tulajdonságot):

<xs:complexType name="név">
    <xs:complexContent>
        <xs:restriction base="alaptípus">
            tartalommodellt megadó elem
            tulajdonságok használatára vonatkozó elemek
        </xs:restriction>
    </xs:complexContent>
</xs:complexType>

[Megjegyzés]Megjegyzés

Megjegyezzük, hogy valójában az anyType típus definíciójának megszorítása minden olyan típusdefiníció, ahol a complexType elemben nem jelenik meg sem az extension, sem a restriction elem. Például a

<xs:complexType>
    <xs:sequence minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="item"/>
    </xs:sequence>
</xs:complexType>

típusdefiníció a következő típusdefinícióval ekvivalens:

<xs:complexType>
    <xs:complexContent>
        <xs:restriction base="xs:anyType">
            <xs:sequence minOccurs="0" maxOccurs="unbounded">
                <xs:element ref="item"/>
            </xs:sequence>
        </xs:restriction>
    </xs:complexContent>
</xs:complexType>

A kiterjesztéstől eltérően a származtatott típus nem örökli az alaptípus tartalommodelljét. A restriction elemben az alaptípus tartalommodelljének egy módosított változata adható meg. Csak olyan módosítások történhetnek az eredeti tartalommodellen, amelyek szűkítik az alaptípus által megengedett tartalmak halmazát, valamint az új típus által megengedett tartalmak meg kell, hogy feleljenek az alaptípus tartalommodelljének is. Például az alábbi módosítások jöhetnek szóba:

  • A minOccurs és maxOccurs tulajdonságok értékének módosítása. (Például az alaptípusnál opcionális elem elhagyása vagy kötelezővé tétele.)

  • Ha az alaptípusnál ezek hiányoznak, akkor alapértelmezett vagy rögzített érték megadása egyszerű típusú elemekhez.

  • Lokális elemdeklarációban szereplő típus helyettesítése egy szűkebb (az eredeti típusból megszorítással származtatott) típussal.

A kiterjesztéshez hasonlóan a származtatott típus örökli az alaptípus tulajdonságait. A restriction elemben a tartalommodellt követően elhelyezhetők az alaptípus tulajdonság-deklarációinak módosított változatai, így megváltoztathatók az alaptípus tulajdonságok használatára vonatkozó előírásai. Csak olyan módosítás végezhető, amely a tulajdonságok használatát szűkíti. Például az alábbi változtatások történhetnek:

  • Alapértelmezett vagy rögzített érték megadása ezek hiányában.

  • Az use tulajdonság értékének módosítása. (Például opcionális tulajdonság használatának kötelezővé tétele vagy megtiltása.)

  • Lokális tulajdonság-deklarációban szereplő egyszerű típus helyettesítése egy szűkebb (az eredeti típusból megszorítással származtatott) egyszerű típussal.

4.24. példa - Komplex típus megszorítása

Legyenek adottak az alábbi sémakomponensek:

<xs:complexType name="PersonType">
    <xs:sequence>
        <xs:choice>
            <xs:sequence>
                <xs:element name="givenName" type="xs:string"/>
                <xs:element name="surname" type="xs:string"/>
            </xs:sequence>
            <xs:element name="name" type="xs:string"/>
        </xs:choice>
        <xs:element name="email" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element name="homePage" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
    <xs:attribute name="nick" type="xs:string" use="optional"/>
</xs:complexType>

<xs:element name="Person" type="PersonType"/>

A PersonType típus az alábbiakat engedi meg tartalomként:

  • Pontosan egy keresztnevet tartalmazó givenName és egy vezetéknevet tartalmazó surname elemet vagy egy teljes nevet tartalmazó name elemet.

  • Tetszőleges számú, egy-egy email címet tartalmazó email elemet.

  • Tetszőleges számú, egy-egy honlapcímet tartalmazó homePage elemet.

Opcionálisként írja elő továbbá a nick tulajdonság használatát. Érvényesek például a PersonType típusúként deklarált Person elem következő előfordulásai:

<Person nick="TimBL">
    <givenName>Timothy John</givenName>
    <surname>Berners-Lee</surname>
    <email>timbl@w3.org</email>
    <homePage>http://www.w3.org/People/Berners-Lee/</homePage>
</Person>

<Person>
    <givenName>Mark</givenName>
    <surname>Zuckerberg</surname>
</Person>

<Person nick="DOS">
    <name>Daniel O’Sullivan</name>
    <email>mothlite@gmail.com</email>
    <homePage>http://www.myspace.com/danielohsullivan</homePage>
    <homePage>http://www.mothlite.org/</homePage>
    <homePage>http://mothlite.blogspot.com/</homePage>
</Person>

Például a következő módon szorítható meg a PersonType típus:

<xs:complexType name="SimplePersonType">
    <xs:complexContent>
        <xs:restriction base="PersonType">
            <xs:sequence>
                <xs:element name="name" type="xs:string"/>
                <xs:element name="email" type="xs:string" minOccurs="1"/>
                <xs:element name="homePage" type="xs:anyURI" minOccurs="0" maxOccurs="1"/>
            </xs:sequence>
            <xs:attribute name="nick" use="required">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:maxLength value="10"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
        </xs:restriction>
    </xs:complexContent>
</xs:complexType>

Az alábbiakban tér el az alaptípus definíciójától a származtatott típus definíciója:

  • Tartalomként pontosan egy name elem kötelező (kizártuk a givenName és a surname alternatívaként történő használatát).

  • Tartalomként pontosan egy email elem kötelező (kötelezővé tettük az opcionális elemet korlátozva az előfordulások számát).

  • Tartalomként legfeljebb egy homePage elem megengedett (korlátoztuk az előfordulások számát).

  • Kötelezővé tettük a nick tulajdonság használatát, amelynek a típusát is megváltoztattuk egyben. A string adattípusból származtatott új adattípusnál a tulajdonságérték legfeljebb 10 karakterből állhat.


4.25. példa - Komplex típus megszorítása

Egy irányított gráf csúcsokból és azokat összekötő irányított élekből áll. Egy irányított gráf látható az alábbi ábrán:

4.1. ábra - Irányított gráf

Irányított gráf


A fenti gráfot ábrázolhatjuk például az alábbi módon:

<graph>
    <node id="N1">
        <hasEdgeTo ref="N2"/>
    </node>
    <node id="N2">
        <hasEdgeTo ref="N3"/>
        <hasEdgeTo ref="N4"/>
    </node>
    <leafNode id="N3"/>
    <leafNode id="N4"/>
</graph>

A graph elemben kétféle elemet használunk a gráf csúcsainak ábrázolásához:

  • A leafNode elemek azoknak a csúcsoknak felelnek meg, amelyekből nem indul egyetlen él sem (ezeket levélcsúcsoknak nevezzük).

  • A node elemek azoknak a csúcsoknak felelnek meg, amelyekből legalább egy él indul (ezeket belső csúcsoknak nevezzük).

Minden csúcshoz egy egyedi azonosítót rendelünk hozzá, amelyet az id tulajdonság hordoz. A node elemekben legalább egy hasEdgeTo elem kötelező, amely a ref tulajdonság értékével egy él végpontját adja meg. Értelemszerű, hogy a leafNode elemeknek nincs tartalma.

Az alábbi sémát alkothatjuk a gráfok fenti formájú leírásához:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:complexType name="NodeType">
        <xs:sequence>
            <xs:element name="hasEdgeTo" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                    <xs:attribute name="ref" type="xs:IDREF" use="required"/>
                </xs:complexType>
            </xs:element>
        </xs:sequence>
        <xs:attribute name="id" type="xs:ID" use="required"/>
    </xs:complexType>

    <xs:complexType name="LeafNodeType">
        <xs:complexContent>
            <xs:restriction base="NodeType"/>
        </xs:complexContent>
    </xs:complexType>

    <xs:element name="graph">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="node" minOccurs="0" maxOccurs="unbounded"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="node" type="NodeType"/>

    <xs:element name="leafNode" type="LeafNodeType" substitutionGroup="node"/>

</xs:schema>

A NodeType komplex típus szolgál a node elem, a LeafNodeType komplex típus pedig a leafNode elem típusául. Figyeljük meg, hogy a LeafNodeType típust megszorítással származtatjuk a NodeType típusból. A restriction elemben nem adunk meg tartalommodellt, megtiltva így a származtatott típus esetén tartalomként elemek és szöveg előfordulását, amely az alaptípus tartalommodelljének szűkítése. A származtatott típus azonban örökli az alaptípus tulajdonság-deklarációit, így a LeafNodeType típusú elemekhez is kötelező az ID tulajdonság.

Figyeljük meg, hogy a leafNode elem deklarációjában a substitutionGroup tulajdonság értékeként a node elem jelenik meg, amely azt jelenti, hogy a leafNode elem helyettesítheti a node elemet. Ez megengedett, mivel a LeafNodeType típust a NodeType típusból származtattuk megszorítással.

A helyettesítési csoport használata miatt a graph elemben tartalomként elég megengedni a node elem előfordulását, mivel helyette bárhol megengedett egy leafNode elem.


Származtatás korlátozása

A típusdefinícióhoz megadható final tulajdonság révén korlátozható a származtatás, amelynek lehetséges értékei és ezek jelentése:

extension

Azt jelenti, hogy nem származtatható a típusdefinícióból kiterjesztéssel új típusdefiníció.

restriction

Azt jelenti, hogy nem származtatható a típusdefinícióból megszorítással új típusdefiníció.

#all

Azt jelenti, hogy nem származtatható a típusdefinícióból kiterjesztéssel és megszorítással sem új típusdefiníció.

Megjegyezzük, hogy a schema elemhez megadható finalDefault tulajdonsággal határozható meg a típusok final tulajdonságának alapértelmezett értéke.

Polimorfizmus

A polimorfizmus az objektumorientált programozásban használt fogalom, amely azt jelenti, hogy egy osztály egy objektuma objektuma egyben az öröklődési hierarchiában valamennyi elődosztálynak. Az XML Schema hierarchikus típusrendszere nagyon hasonló az objektumorientált programozási nyelvek osztályhierarchiájához: a típusok megfeleltethetők az osztályoknak, a típussal rendelkező elemek pedig az objektumoknak. A hasonlóság nem véletlen, az objektumorientált programozási nyelvek alapul szolgáltak az XML Schema típusrendszerének kidolgozásához.

A polimorfizmus az XML Schema esetén két formában is megjelenik. A helyettesítési csoportok képviselik a polimorfizmus egyik formáját, amelyek lehetővé teszik adott elemek más elemekkel történő helyettesítését a példányokban.

A polimorfizmus egy másik formája az, hogy a példányokban egy elem előfordulásaihoz használható az elem típusából származtatott bármely típus. A 4.26. példa - Polimorfizmus szemlélteti, hogy ez pontosan mit is jelent.

4.26. példa - Polimorfizmus

Tekintsük a 4.22. példa - Komplex típus kiterjesztése némileg módosított alábbi sémakomponenseit:

<xs:complexType name="eventType">
    <xs:sequence>
        <xs:element name="date" type="xs:date"/>
        <xs:element name="place" type="xs:string"/>
    </xs:sequence>
</xs:complexType>

<xs:element name="birth" type="eventType"/>

<xs:complexType name="DeathType">
    <xs:complexContent>
        <xs:extension base="eventType">
            <xs:sequence>
                <xs:element name="cause" type="xs:string" minOccurs="0"/>
            </xs:sequence>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

<xs:element name="death" type="DeathType"/>

Mindössze annyi változott, hogy a death elem típusát felső szinten definiáltuk DeathType néven, nem pedig névtelen típusként. Ez a típus az eventType típusból származik, ezért a példányokban megjelenhet a birth elem típusaként is. A következő módon használhatjuk dokumentumokban az elemhez a származtatott típust:

<birth xsi:type="DeathType">
    <date>1981-12-02</date>
    <place>McComb, Mississippi, U.S.</place>
    <cause>OOPS</cause>
</birth>

Figyeljük meg, hogy a születési adatokat tartalmazó elemben megjelent a halál okát tartalmazó cause elem. Ez teljesen legális, noha esetünkben nem kívánatos, hogy megengedett legyen. Az xsi:type tulajdonság értékeként annak a típusnak a nevét adjuk meg, amely alapján a dokumentumon érvényesítést végző XML feldolgozó el kell, hogy végezze az elem érvényesítését (ehhez alapértelmezésben a birth elem eredeti típusát használja, így természetesen az xsi:type tulajdonság hiányában a fenti elem nem lenne érvényes).

A típusok egymásból történő származtatásának fenti mellékhatása egyszerűen kiküszöbölhető, ehhez csupán az alábbi módosítás szükséges az eventType típus definíciójában:

<xs:complexType name="eventType" block="extension">
    <xs:sequence>
        <xs:element name="date" type="xs:date"/>
        <xs:element name="place" type="xs:string"/>
    </xs:sequence>
</xs:complexType>


Polimorfizmus korlátozása.  A polimorfizmus a típusdefinícióhoz megadható block tulajdonság révén korlátozható, amelynek lehetséges értékei és ezek jelentése:

extension

Azt jelenti, hogy a típus helyett nem használható belőle kiterjesztéssel származtatott típus.

restriction

Azt jelenti, hogy a típus helyett nem használható belőle megszorítással származtatott típus.

#all

Azt jelenti, hogy a típus helyett nem használható belőle kiterjesztéssel és megszorítással származtatott típus sem.

Megjegyezzük, hogy a schema elemhez megadható blockDefault tulajdonsággal határozható meg a típusok block tulajdonságának alapértelmezett értéke.

Absztrakt típusok

Típusdefiníciókhoz megadható a logikai értékű abstract tulajdonság, amelynek true értéke esetén a típusdefiníció csupán alaptípusként szolgálhat más típusok származtatásához, de nem használható fel közvetlenül elemek típusaként (a tulajdonság alapértelmezett értéke false). Az alábbi példával szemléltetjük az absztrakt típusok használatát.

4.27. példa - Absztrakt típus használata

Tekintsük az alábbi sémakomponenseket:

<xs:simpleType name="isbn">
    <xs:restriction base="xs:string">
        <xs:pattern value="\d{13}"/>
	</xs:restriction>
</xs:simpleType>

<xs:simpleType name="issn">
    <xs:restriction base="xs:string">
        <xs:pattern value="\d{4}-\d{3}[\dX]"/>
    </xs:restriction>
</xs:simpleType>

<xs:complexType name="PublicationType" abstract="true">
    <xs:sequence>
        <xs:element name="title" type="xs:string"/>
        <xs:element name="publisher" type="xs:string"/>
    </xs:sequence>
</xs:complexType>

<xs:complexType name="BookType">
    <xs:complexContent>
        <xs:extension base="PublicationType">
            <xs:sequence>
                <xs:element name="isbn" type="isbn"/>
            </xs:sequence>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

<xs:complexType name="PeriodicalType">
    <xs:complexContent>
        <xs:extension base="PublicationType">
            <xs:sequence>
                <xs:element name="issn" type="issn"/>
            </xs:sequence>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

<xs:element name="Publication" type="PublicationType"/>

<xs:element name="Publications">
    <xs:complexType>
        <xs:sequence>
            <xs:element ref="Publication" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>

A Publication elem típusaként megjelenő PublicationType típus absztrakt, amelyből kiterjesztéssel származtatottak a BookType és PeriodicalType konkrét típusok. Mivel a Publication elem nem absztrakt, minden további nélkül előfordulhat a példányokban. Példányokban nem megengedett azonban az alábbi Publication elemek egyike sem, mert érvényesítéshez nem használható az absztrakt típus:

<Publication>
    <title>...</title>
    <publisher>...<publisher>
</Publication>

<Publication xsi:type="PublicationType">
    <title>...</title>
    <publisher>...<publisher>
</Publication>

Kizárólag olyan Publication elemek fordulhatnak elő példányokban, amelyekhez az xsi:type tulajdonság értékeként valamelyik konkrét származtatott típus nevét adjuk meg, mint például:

<Publication xsi:type="PeriodicalType">
    <title>Journal of Statistical Software</title>
    <publisher>American Statistical Association</publisher>
    <issn>1548-7660</issn>
</Publication>

<Publication xsi:type="BookType">
    <title>World War Z &#8211; Zombiháború</title>
    <publisher>Könyvmolyképző Kiadó</publisher>
    <isbn>9789632452753</isbn>
</Publication>

Az érvényesítéshez értelemszerűen a megfelelő típusdefiníció kerül felhasználásra.

Megjegyezzük, hogy a PublicationType absztrakt típus definiálható a következő módon is:

<xs:complexType name="PublicationType" abstract="true">
    <xs:sequence>
        <xs:element name="title" type="xs:string"/>
        <xs:element name="publisher" type="xs:string"/>
        <xs:choice>
            <xs:element name="isbn" type="isbn"/>
            <xs:element name="issn" type="issn"/>
        </xs:choice>
    </xs:sequence>
</xs:complexType>

Ekkor a BookType és PeriodicalType típusok definíciói megszorítással származtathatóak a PublicationType típus definíciójából. Ennek gyakorlati megvalósítását az olvasóra hagyjuk feladatként.


Az anyType típus

A típusdefiníciók hierarchiájának gyökerét reprezentáló anyType típus szabadon használható fel elemek típusaként, akár a többi közönséges komplex típus. Tartalommodellje kötetlen, amely semmiféle megszorítást nem ír elő a tartalomra. Tetszőleges számban és sorrendben engedi meg gyermekként szöveg és tetszőleges elemek előfordulását, tulajdonságok használatát azonban nem teszi lehetővé. A tartalomban gyermekként vagy leszármazottként megjelő elemek tartalmára sem vonatkozik megkötés, amelyekhez tetszőlegesen adhatók meg tulajdonságok is. Kivételt képeznek a deklarált elemek, amelyek használata csak a deklarációknak megfelelően történhet.

4.28. példa - Az anyType típus használata

Az alábbi módon deklarált elemben tetszőleges tartalom megengedett:

<xs:element name="anything" type="xs:anyType"/>

Érvényes például az anything elem következő előfordulása:

<anything>
    Ez az <elem> megengedi, hogy tartalomként <tetszőleges/> sok tetszőleges </elem>
    és szöveg forduljon elő benne.
 </anything>


Helyettesítők

Ebben a szakaszban az elem- és tulajdonság-helyettesítőket, összefoglaló nevükön helyettesítőket (wildcards) mutatjuk be, amelyek nagyfokú rugalmasságot biztosítanak a sémákban. A két helyettesítő használatának módja nagyon hasonló, ezért együtt kerülnek tárgyalásra.

A sequence és choice modellcsoportokban rendelkezésre álló elemhelyettesítő tetszőleges nevű elemek előfordulását engedi meg. A komplex típusok definícióiban és tulajdonságcsoport-definíciókban rendelkezésre álló tulajdonság-helyettesítők pedig hasonlóan engedik meg tetszőleges nevű tulajdonságok használatát. Az elemhelyettesítőt az any elem, a tulajdonság-helyettesítőt pedig az anyAttribute elem reprezentálja az XML Schema névtérben. Az anyAttribute elem típusdefiníciókban és modellcsoport-definíciókban egyaránt csak a tulajdonság-deklarációkat követően szerepelhet legfeljebb egyszer.

Mindkét elemhez megadható az opcionális namespace tulajdonság, amely révén korlátozható a helyettesítő által megengedett elemek (tulajdonságok) halmaza. Lehetséges értékei és ezek jelentése:

##any

Minden elem (tulajdonság) megengedése (ez az alapértelmezés).

##local

Csak névtérbe nem tartozó nevű elemek (tulajdonságok) megengedése.

##other

Csak a cél-névtértől különböző névtérbe tartozó nevű elemek (tulajdonságok) megengedése (nem megengedek azonban névtérbe nem tartozó nevű elemek és tulajdonságok).

##targetNamespace

Csak a cél-névtérbe tartozó nevű elemek (tulajdonságok) megengedése.

URI

Az adott URI által azonosított névtérbe tartozó nevű elemek (tulajdonságok) megengedése.

Megjegyezzük, hogy a tulajdonság értékében a fentiek közül akár többet is meg lehet adni szóköz karakterekkel elválasztva (az ##any és a ##local opciót kivéve, amelyek csak önmagukban szerepelhetnek).

Mindkét elemhez megadható az opcionális processContents tulajdonság, amely azt írja elő, hogy az érvényesítés során hogyan történjen a helyettesítőnek megfeleltetett elemek (tulajdonságok) feldolgozása. A tulajdonság lehetséges értékei és jelentésük (az alapértelmezés strict):

skip

Azt jelenti, hogy ezeken az elemeken (tulajdonságokon) nem kell érvényesítést végezni (csak a jólformázottsági megszorításoknak kell megfelelniük).

lax

Azt jelenti, hogy csak akkor kell érvényesítést végezni ezeken az elemeken (tulajdonságokon), ha deklaráltak (azaz nem deklarált elemek és tulajdonságok korlátozás nélkül használhatók).

strict

Azt jelenti, hogy mindenképpen érvényesítést kell végezni ezeken az elemeken (tulajdonságokon) (nem deklarált elemek és tulajdonságok használatának kizárása).

Egy-egy példán keresztül mutatjuk be alább a helyettesítők alkalmazását.

4.29. példa - Elemhelyettesítő használata

Az alábbi módon deklarált comment elemben tartalomként tetszőleges számú olyan elem megengedett, amelyek neve az XHTML névtérbe tartozik:

<xs:element name="note">
    <xs:complexType>
        <xs:sequence>
            <xs:any namespace="http://www.w3.org/1999/xhtml" minOccurs="0"
                maxOccurs="unbounded" processContents="lax"/>
	       </xs:sequence>
    </xs:complexType>
</xs:element>

A comment elem egy lehetséges előfordulása:

<note>
    <p xmlns="http://www.w3.org/1999/xhtml">See
        <a href="http://www.w3.org/XML/Schema">http://www.w3.org/XML/Schema</a>
        for more information.</p>
</note>


[Figyelem]Figyelem

Megjegyezzük, hogy elemhelyettesítő csak az egyértelműséget nem sértő módon használható modellcsoportban. Tilos például az alábbi:

<xs:sequence>
    <xs:any processContents="lax" maxOccurs="unbounded"/>
    <xs:element ref="A"/>
</xs:sequence>

4.30. példa - Tulajdonság-helyettesítő használata

Az alábbi módon deklarált myLink elemhez tetszőleges olyan tulajdonság megengedett, amelyek neve az XLink névtérbe tartozik:

<xs:element name="myLink">
    <xs:complexType>
        <xs:simpleContent>
            <xs:extension base="xs:string">
                <xs:anyAttribute namespace="http://www.w3.org/1999/xlink"
                    processContents="lax"/>
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>
</xs:element>

A myLink elem egy lehetséges előfordulása:

<myLink xmlns:xlink="http://www.w3.org/1999/xlink"
    xlink:type="simple" xlink:href="http://www.w3.org/">
    World Wide Web Consortium (W3C)
</myLink>


Feladatok

  1. Legyenek A, B és C globális elemek. Adjuk meg minden alábbi modellcsoportra, hogy megengedett-e vagy sem.

    1. <xs:sequence>
          <xs:element ref="A" maxOccurs="unbounded"/>
          <xs:element ref="B" minOccurs="0"/>
          <xs:element ref="A"/>
      </xs:sequence>
    2. <xs:sequence>
          <xs:element ref="A"/>
          <xs:element ref="B" minOccurs="0"/>
          <xs:element ref="A" maxOccurs="unbounded"/>
      </xs:sequence>
    3. <xs:sequence>
          <xs:element ref="A" maxOccurs="10"/>
          <xs:element ref="B" minOccurs="0"/>
          <xs:element ref="A" minOccurs="1" maxOccurs="5"/>
      </xs:sequence>
  2. Legyenek A és B globális elemek. Adjuk meg minden alábbi modellcsoportra, hogy megengedett-e vagy sem.

    1. <xs:sequence>
          <xs:element ref="A" minOccurs="0"/>
          <xs:choice>
              <xs:element ref="A"/>
              <xs:element ref="B"/>
          </xs:choice>
      </xs:sequence>
    2. <xs:sequence>
          <xs:choice>
              <xs:element ref="A"/>
              <xs:element ref="B"/>
          </xs:choice>
          <xs:element ref="A" minOccurs="0"/>
      </xs:sequence>
    3. <xs:sequence>
          <xs:element ref="A"/>
              <xs:choice>
                  <xs:element ref="A"/>
                  <xs:element ref="B" minOccurs="0"/>
              </xs:choice>
      </xs:sequence>
  3. Legyen A globális elem. Adjuk meg minden alábbi modellcsoportra, hogy megengedett-e vagy sem.

    1. <xs:sequence>
          <xs:element ref="A"/>
          <xs:any processContents="skip"/>
      </xs:sequence>
    2. <xs:choice>
          <xs:element ref="A"/>
          <xs:any processContents="skip"/>
      </xs:choice>
    3. <xs:sequence>
          <xs:element ref="A" minOccurs="0"/>
          <xs:any processContents="skip"/>
      </xs:sequence>
  4. Legyen item egy globális elem. Adj meg egy olyan modellcsoportot, amely tartalomként az alábbiakat engedi meg:

    1. Kizárólag páratlan számú item elem előfordulását.

    2. Kizárólag 0, 5, 10, 15, 20, … számú item elem előfordulását.

  5. Deklaráld az alábbi példában látható elemeket, amelyeket egy önéletrajzban használhatunk munkahelyek és munkakörök leírásához:

    <jobs>
        <job>
            I worked as an <jobTitle>associate professor</jobTitle> 
            at the <company>University of Zürich</company>
            between <from>1909</from> and <to>1911</to>.    
        </job>
        <job>
            Since <from>1911</from> I am a <jobTitle>professor</jobTitle>
            at the <company>German University of Prague.</company>
        </job>
        ...
    </jobs>

    Minden job elemben kötelező a szövegben pontosan egy company, jobTitle és from elem, valamint megadható egy opcionális to elem, amelyek sorrendje tetszőleges lehet.

  6. Egy irányított gráf csúcsokból és azokat összekötő irányított élekből áll. Egy irányított gráf látható az alábbi ábrán.

    4.2. ábra - Példa irányított gráfra

    Példa irányított gráfra

    Az ábrán látható irányított gráfot például az alábbi módon írhatjunk le egy XML dokumentumban:

    <graph>
    
        <node id="A">1</node>
        <node id="B">2</node>
    
        <edge source="A" target="C">E1</edge>
        <edge source="A" target="D">E2</edge>
        <edge source="B" target="D">E3</edge>
        <edge source="B" target="G">E4</edge>
    
        <node id="C">3</node>
        <node id="D">4</node>
        <node id="E">5</node>
    
        <edge source="E" target="A">E5</edge>
    
        <node id="F">6</node>
        <node id="G">7</node>
     
        <edge source="F" target="A">E6</edge>
        <edge source="F" target="G">E7</edge>
        <edge source="G" target="C">E8</edge>
    
    </graph>

    Egy olyan megoldást választottunk, amelyben a csúcsokat node elemek, az éleket pedig edge ábrázolják. Minden csúcshoz egy egyedi azonosító tartozik, amelyet az id tulajdonság hordoz. Egy edge elem from és to tulajdonságainak értékeként az él által összekötött csúcsok azonosítói jelennek meg. A node és edge elemek egy olyan szöveget tartalmaznak, amelyet a gráf megjelenítésnél címkeként lehet használni.

    Készíts sémát az imént bemutatott formátumhoz. A csúcsok azonosításához használjuk az ID és IDREF adattípusokat.

  7. Tekintsük az alábbi, egy menürendszert leíró dokumentumot:

    <menu name="Main">
        <menu name="File">
            <menu name="New">
                <item name="XML Document"/>
                <item name="XML Schema"/>
            </menu>
            <item name="Open"/>
            <item name="Save"/>
        </menu>
        <menu name="Edit">
            <item name="Cut"/>
            <item name="Copy"/>
            <item name="Paste"/>
        </menu>
    </menu>

    A menu elem item és további menu elemeket tartalmazhat gyermekként tetszőleges számban és sorrendben, az item elem pedig üres. Mindkét elemhez kötelező a name tulajdonság megadása. Feltevés szerint a menu elemek tetszőleges mélységig skatulyázhatók egymásba.

    Készíts a dokumentumhoz sémát két változatban is: az elsőben a menu és item elemekhez tartozó típusdefiníciók nem származtathatóak egymásból, a másikban viszont a két típusdefiníció valamelyikét a másikból származtasd.

  8. Egy bináris kifejezésfák ábrázolására szolgáló XML formátumot tekintünk ebben a feladatban. A bináris kifejezésfa olyan speciális bináris fa, amelynek levélcsúcsai operandusokat tárolnak, a többi csúcs pedig kétoperandusú (aritmetikai) operátorokat ábrázol. Legyenek az operandusok double típusú lebegőpontos számok. Alább bináris kifejezésfák egy lehetséges ábrázolását láthatjuk:

    <node op="/">
        <node op="+">
            <number>1280</number>
            <node op="*">
                <number>23.85</number>
                <number>312.63</number>
            </node>
        </node>
        <number>2</number>
    </node>

    A fenti fának megfelelő aritmetikai kifejezés infix alakban felírva (1280+(23.85*312.63))/2.

    A bináris fa levélcsúcsainak a dokumentumban a number elemek felelnek meg, az operátorok csúcsainak pedig a node elemek. A fa csúcsai közötti szülő-gyermek kapcsolatokat az elemek egymásba ágyazásával fejezzük ki. Minden node elem pontosan két elemgyermeket tartalmaz, amelyek mindegyike egy number elem vagy egy másik node elem. A node elem op tulajdonsága tárolja a csúcshoz tartozó aritmetikai operátort. Készíts sémát a fenti formátumhoz.



[4] A szöveg Bram Stoker Drakula gróf válogatott rémtettei című művéből származik, Bartos Tibor fordítása.

5. fejezet - Azonossági megszorítások

Bevezetés

A DTD-ben rendelkezésre álló ID, IDREF és IDREFS tulajdonságtípusok hivatkozható egyedi azonosítók használatát teszik lehetővé XML dokumentumokban. Alkalmazásukra az alábbi korlátozások vonatkoznak:

  • Kizárólag tulajdonságokhoz biztosított egyedi azonosítók ellenőrzött használata.

  • Minden azonosító kötelezően XML név.

  • Minden azonosító globális a teljes dokumentumra nézve.

  • Minden elemhez legfeljebb egy ID típusú tulajdonság deklarálható.

[Megjegyzés]Megjegyzés

Az XML séma beépített adattípusként biztosítja a DTD azonos nevű tulajdonságtípusainak megfelelő ID, IDREF és IDREFS típusokat, amelyeket kompatibilitási okokból kizárólag tulajdonságok típusaként ajánlott használni.

XML sémákban egyedi azonosítók kezeléséhez olyan azonossági megszorításoknak nevezett konstrukciók adottak, amelyek lehetőségei messze meghaladják a DTD kifejező erejét. Az azonossági megszorítások előnyei:

  • Az azonosítók egyediségének követelménye adott hatáskörre korlátozható.

  • Tetszőleges adattípusokkal használhatók.

  • Azonosítók egyezésének vizsgálatánál nem egyszerűen karakterláncok hasonlítása történik, hanem az értéktér megfelelő elemeinek hasonlítása.

  • Egyszerű típusú elemekhez és tulajdonságokhoz is használhatók.

  • Nem csak egyedi elemekhez és tulajdonságokhoz használhatók, hanem ezek tetszőleges kombinációihoz is.

Három fajta azonossági megszorítás áll rendelkezésre:

  • key

  • unique

  • keyref

Míg az első kettő egyediség előírására szolgál, a harmadik hivatkozási megszorítás.

Azonossági megszorítások definiálása

Azonossági megszorítások definiálása elemdeklarációkban történik. Minden elemdeklarációban tetszőleges számú azonossági megszorítást definiáló sémakomponens adható meg, amelyek az opcionális kommentárt és típusdefiníciót követik. A továbbiakban egy azonossági megszorítás kapcsán deklarált elemnek azt az elemet nevezzük, amelynek deklarációja a megszorítást definiáló sémakomponenst tartalmazza.

Minden azonossági megszorításhoz egy olyan egyedi azonosítót kell megadni a definiáló elem name tulajdonságának értékeként, amely egy kettőspont karaktert nem tartalmazó XML név.

Mindhárom azonossági megszorításban két lépésben történik a résztvevő elemek és tulajdonságok kijelölése:

  1. Egy selector elemmel ki kell választani a deklarált elemhez képest bizonyos elemeket.

  2. A selector elem által kijelölt elemekhez képest egy-egy field elemben kell kiválasztani minden a megszorításban résztvevő elemet és tulajdonságot.

Ehhez a selector és field elemekben az xpath tulajdonság értékeként XPath [XPath] elérési útvonalakat kell megadni.

Egyetlen field elem megadásával egyszerű kulcsok, kettő vagy több használatával pedig összetett kulcsok kezelését lehet megvalósítani.

XPath elérési útvonalak

A sémákban szigorú formai előírások vonatkoznak az xpath tulajdonság értékeként megadható elérési útvonalakra. A megvalósítások készítését egyszerűsíti, hogy csupán az elérési útvonalak egy részhalmaza megengedett, a rövidített szintaxissal megadott relatív elérési útvonalak használhatók korlátozott módon.

Az elérési útvonalak a deklaráló elem, a deklaráló elem elemgyermekeinek, valamint ezek tulajdonságainak kiválasztására szolgálnak, amely elegendőek a child és attribute irányok.

A selector és field elemekhez tartozó elérési útvonalakban az alábbi lépések szerepelhetnek:

.
*
minősített_név
előtag:*

A field elemekhez tartozó elérési útvonalak kiválaszthatnak tulajdonságokat is, ezért ezek utolsó lépése lehet az alábbiak valamelyike is:

@*
@minősített_név
@előtag:*

A lépésekben minősített_név egy tetszőleges, de legfeljebb egy kettőspont karaktert tartalmazó XML név, előtag pedig kettőspont karaktert nem tartalmazó tetszőleges XML név.

Minden elérési útvonal elején megadható továbbá a .// rövidítés, a selector elemeknél pedig rendelkezésre áll a | operátor elérési útvonalak kombinálásához.

A sémára vonatkozó megszorítások ellenőrzésekor az elérési útvonalak csak formailag kell hogy megfeleljenek az előírásoknak. Formailag helyes elérési útvonalak az érvényesítés során eredeményeznek hibát.

Szemantika

A selector elérési útvonal kiértékelése a deklarált elemhez relatívan történik az érvényesítés során. Mindhárom azonossági megszorítás esetén kötelező az érvényességhez, hogy az elérési útvonal csak a deklarált elemet vagy a benne leszármazottként tartalmazott elemeket választhatja ki a dokumentumban.

A field elemekhez tartozó elérési útvonalak kiértékelése a selector elérési útvonal által kijelölt elemekhez relatívan történik. Mindhárom azonossági megszorítás esetén kötelező az érvényességhez, hogy minden field elérési útvonal minden kiértékelése során legfeljebb egy egyszerű típusú elem vagy tulajdonság kerüljön kiválasztásra.

key

A key azonossági megszorítás szemléletesen azt fejezi ki, hogy a selector által kiválasztott elemekhez a field elemek olyan elemeket és tulajdonságokat választanak ki, amelyek páronként különböző értékkombinációkat határoznak meg, és hogy ezek az értékombinációk minden a selector által kiválasztott elemhez hiánytalanul rendelkezésre állnak.

Minden key azonossági megszorításra az alábbiak kell hogy teljesüljenek az érvényességhez:

  1. A selector által kiválasztott elemekhez a field elemek mindegyike pontosan egy egyszerű típusú elemet vagy tulajdonságot választ ki.

  2. A field elemek által kiválasztott elemek egyikének deklarációjához sem tartozik true értékű nillable tulajdonság.

  3. A selector által kiválasztott elemekhez a field elemek olyan értékkombinációkat választanak ki, amelyek páronként különböznek.

A selector által kiválasztott elemekhez a field elemek által kiválasztott értékkombinációkat kulcssorozatoknak nevezzük. A kulcssorozatok eltérésének megállapításához a field elemekkel kiválasztott egyszerű típusú elemekben és tulajdonságokban hordozott értékek kerülnek páronként összehasonlításra.

A kulcssorozatok a fentiek szerint a deklaráló elemen belül egyértelműen azonosítják a selector által kijelölt elemeket, ezért jogosan tekinthetjük ezeket kulcsoknak.

keyref

A keyref azonossági megszorítás ellenőrzött hivatkozást tesz lehetővé az adott key vagy unique azonossági megszorításhoz tartozó kulcssorozatokra.

Minden keyref azonossági megszorításra az alábbiak kell hogy teljesüljenek az érvényességhez:

  1. A keyref azonossági megszorítás definícióját tartalmazó elemdeklaráció gyermekként vagy leszármazottként tartalmazza a refer tulajdonságban megnevezett key vagy unique azonossági megszorítás definícióját.

  2. Ha valamely a selector által kiválasztott elemhez minden field elem pontosan egy egyszerű típusú elemet elemet vagy tulajdonságot választ ki, akkor az általuk meghatározott kulcssorozat megegyezik a keyref tulajdonságban adott key vagy unique azonossági megszorítás által meghatározott valamely kulcssorozattal.

Egy keyref megszorításhoz a refer tulajdonságban megnevezett key vagy unique azonossági megszorítás viszonya megfelel a DTD-ben rendelkezésre álló ID és IDREF tulajdonságtípusok kapcsolatának.

unique

A unique a key-hez hasonló azonossági megszorítás, amelytől eltér abban, hogy a selector által kiválasztott elemekhez nem teszi kötelezővé a kulcsokként funkcionáló kulcssorozatok létezését a dokumentumokban. Míg a key azonossági megszorításokban a field elemek pontosan egy egyszerű típusú elemet vagy tulajdonságot kell hogy kiválasszanak minden a selector által kiválasztott elemekhez, a unique esetén a field elemekhez tartozó elérési útvonalak kiértékelésének eredményeként megengedett az üres halmaz. Az egyediség követelménye csak a hiánytalanul rendelkezésre álló kulcssorozatokra vonatkozik. A unique azonossági megszorítások is használhatók a keyref azonossági megszorításokhoz a kulcsokra történő ellenőrzött hivatkozások megvalósításához.

Minden unique azonossági megszorításra az alábbiak kell hogy teljesüljenek az érvényességhez:

  1. Páronként különböznek azokhoz a selector által kiválasztott elemekhez tartozó kulcssorozatok, amelyekhez minden field elem pontosan egy egyszerű típusú elemet vagy tulajdonságot választ ki.

Példák

5.1. példa - A key azonossági megszorítás

Tekintsük az alábbi elemdeklarációkat:

<xs:element name="books">
    <xs:complexType>
        <xs:sequence>
            <xs:element ref="book" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>
    <xs:key name="book-key">
        <xs:selector xpath="book"/>
        <xs:field xpath="isbn"/>
    </xs:key>
</xs:element>

<xs:element name="book">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="author" type="xs:string"/>
            <xs:element name="title" type="xs:string"/>
            <xs:element name="isbn">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:pattern value="\d{13}"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>
</xs:element>

A books elem egy lehetséges előfordulása például:

<books>
    <book>
        <author>Mihail Bulgakov</author>
        <title>A Mester és Margarita</title>
        <isbn>9789630787208</isbn>
    </book>
    <book>
        <author>George  Orwell</author>
        <title>1984</title>
        <isbn>9789630788120</isbn>
    </book>
    <book>
        <author>Umberto Eco</author>
        <title>A rózsa neve</title>	
        <isbn>9789630785785</isbn>
    </book>
    <book>
        <author>Bram Stoker</author>
        <title>Drakula</title>
        <isbn>9879630789448</isbn>
    </book>
</books>

A books elem deklarációjában a key azonossági megszorítás azt jelenti, hogy a book elemek isbn elemgyermekeiben tartalmazott ISBN-számok között nem lehetnek azonosak.


5.2. példa - A key azonossági megszorítás

Tekintsük az alábbi elemdeklarációkat:

<xs:element name="winning.numbers">
    <xs:complexType>
        <xs:sequence>
            <xs:element ref="number" minOccurs="5" maxOccurs="5"/>
        </xs:sequence>
    </xs:complexType>
    <xs:key name="number-key">
        <xs:selector xpath="number"/>
        <xs:field xpath="."/>
    </xs:key>
</xs:element>

<xs:element name="number">
    <xs:simpleType>
        <xs:restriction base="xs:integer">
            <xs:minInclusive value="1"/>
            <xs:maxInclusive value="90"/>
        </xs:restriction>
    </xs:simpleType>
</xs:element>

A winning.numbers elem egy lehetséges előfordulása például:

<winning.numbers>
    <number>25</number>
    <number>32</number>
    <number>36</number>
    <number>43</number>
    <number>63</number>
</winning.numbers>

A winning.numbers elem az ötöslottó nyerőszámainak megadását teszi lehetővé, amelynek deklarációjában tartalmazott key azonossági megszorítás azt a természetes követelményt fejezi ki, hogy a nyerőszámok között nem lehetnek azonosak. A field elemhez elérési útvonalként . magukat a selector által kiválasztott number elemeket jelenti.


5.3. példa - A key azonossági megszorítás

Tekintsük az alábbi elemdeklarációkat:

<xs:element name="polygon">
    <xs:complexType>
        <xs:sequence>
            <xs:element ref="point" minOccurs="3" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>
    <xs:key name="point-key">
        <xs:selector xpath="point"/>
        <xs:field xpath="@x"/>
        <xs:field xpath="@y"/>
    </xs:key>
</xs:element>

<xs:element name="point">
    <xs:complexType>
        <xs:attribute name="x" type="xs:double" use="required"/>
        <xs:attribute name="y" type="xs:double" use="required"/>
    </xs:complexType>
</xs:element>

A polygon elem egy lehetséges előfordulása például:

<polygon>
    <point x="3.8442821" y="4.305204"/>
    <point x="-1.7082156" y="-2.092814"/>
    <point x="-0.6634852" y="-4.986617"/>
</polygon>

A polygon elem egy sokszöget határoz meg, amelyhez legalább három olyan point elemgyermek kötelező, amelyek mindegyike egy-egy csúcsot ad meg. A key azonossági megszorítás azt fejezi ki a deklarációban, hogy a csúcsok mind különböző pontok, tehát nem egyezhetnek meg két különböző point elem x és y tulajdonságának értékeként megjelenő double típusú értékek.


5.4. példa - A key és keyref azonossági megszorítás

Tekintsük az alábbi elemdeklarációkat:

<xs:element name="dictionary">
    <xs:complexType>
        <xs:sequence>
            <xs:element ref="entry" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>
    <xs:key name="entry-key">
        <xs:selector xpath="entry"/>
        <xs:field xpath="term"/>
    </xs:key>
    <xs:keyref name="entry-ref" refer="entry-key">
        <xs:selector xpath="entry/see"/>
        <xs:field xpath="."/>
    </xs:keyref>
</xs:element>

<xs:element name="entry">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="term" type="xs:string"/>
            <xs:element name="definition" type="xs:string"/>
            <xs:element name="see" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>

A dictionary elem egy lehetséges előfordulása például:

<dictionary>
    <entry>
        <term>Internet</term>
        <definition>A TCP/IP protokollra épülő globális számítógép-hálózat.</definition>
    </entry>
    <entry>
        <term>World Wide Web (WWW)</term>
        <definition>Az Interneten működő globális hipertext rendszer.</definition>
        <see>Internet</see>
        <see>World Wide Web Consortium (W3C)</see>
    </entry>
    <entry>
        <term>World Wide Web Consortium (W3C)</term>
        <definition>WWW szabványokért felelős nemzetközi szervezet.</definition>
        <see>World Wide Web (WWW)</see>
    </entry>
</dictionary>

A dictionary elem minden entry elemgyermeke egy kifejezés meghatározását hordozza. A term elem a definiálandó kifejezést, a definition elem a meghatározást tartalmazza, a see elemekben pedig a kapcsolódó kifejezéseket lehet megadni.

A key azonossági megszorítás azt fejezi ki, hogy minden kifejezés csak egyszer definiálható, azaz az entry elemek term elemgyermekeiben tartalmazott karakterláncok páronként különböznek.

A keyref azonossági megszorítás azt fejezi ki, hogy a see elemekben csak olyan karakterláncok megengedettek, amelyeket egy entry elem term elemgyermeke tartalmaz. Kézenfekvőnek tűnhet

<xs:keyref name="entry-ref" refer="entry-key">
    <xs:selector xpath="entry"/>
    <xs:field xpath="see"/>
</xs:keyref>

módon definiálni az azonossági megszorítást, amely azonban hibát eredményezhet az érvényesítés során. A field elemhez tartozó elérési útvonal az entry elemekhez relatív kiértékelése valamennyi see elemgyermek kiválasztását eredményezi, amelyek tetszőleges számban fordulhatnak elő az entry elemekben, a field elemek azonban legfeljebb egy elemet választhatnak ki a selector elemekhez kiválasztott elemekhez. A fenti azonossági megszorítás csak akkor nem okoz hibát, ha minden entry elemben legfeljebb egy see elem jelenik meg, amely nem garantálható. Megoldásként a selector elemhez az entry/see elérési útvonalat, a field elemhez pedig a . elérési útvonalat kell megadni.

Mivel a term és see elemek string típusúként deklaráltak, ezekben minden egyes whitespace karakter szignifikáns! Ez azt jelenti, hogy a fenti példányban például a <see>World Wide Web (WWW)</see> elem nem helyettesíthető a <see>World Wide Web (WWW) </see> elemmel. Ha a whitespace karaktereket figyelmen kívül lehet hagyni, használjuk a string típus helyett a token típust, amelynél automatikus whitespace-normalizálás történik.


5.5. példa - A key és keyref azonossági megszorítás

Legyen adott az alábbi sémadokumentum, amely családfák XML-ben ábrázolásához készült:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:element name="genealogy">
        <xs:complexType>
            <xs:choice minOccurs="0" maxOccurs="unbounded">
                <xs:element ref="person"/>
                <xs:element ref="family"/>
            </xs:choice>
        </xs:complexType>
    </xs:element>

    <xs:element name="person">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="name" type="xs:string"/>
            </xs:sequence>
            <xs:attribute name="id" type="xs:nonNegativeInteger" use="required"/>
        </xs:complexType>
    </xs:element>

    <xs:element name="family">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="husband" type="ref"/>
                <xs:element name="wife" type="ref"/>
                <xs:element name="child" type="ref" minOccurs="0" maxOccurs="unbounded"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:complexType name="ref">
        <xs:attribute name="ref" type="xs:nonNegativeInteger" use="required"/>
    </xs:complexType>

</xs:schema>

A genealogy elem egy lehetséges előfordulása például:

<genealogy>
    <person id="1">
        <name>David Poe, Jr.</name>
    </person>
    <person id="2">
        <name>Elizabeth Arnold Hopkins</name>
    </person>
    <person id="3">
        <name>Edgar Allan Poe</name>
    </person>
    <person id="4">
        <name>Rosalie Mackenzie Poe</name>
    </person>
    <person id="5">
        <name>William Henry Leonard Poe</name>
    </person>
    <person id="6">
        <name>Virginia Clemm</name>
    </person>
    <family>
        <husband ref="1"/>
        <wife ref="2"/>
        <child ref="3"/>
        <child ref="4"/>
        <child ref="5"/>
    </family>
    <family>
        <husband ref="3"/>
        <wife ref="6"/>
    </family>
</genealogy>

A genealogy elem kétféle elemet tartalmazhat gyermekként, amelyek tetszőleges számban és sorrendben fordulhatnak elő: személyeket reprezentáló person, valamint közöttük fennálló családi kapcsolatokat reprezentáló family elemeket. Jól látható, hogy a személyeket az id tulajdonság értékeként adott olyan nemnegatív egész számokkal azonosítjuk, amelyeket a kapcsolatokban a ref tulajdonság értékeként használunk a megfelelő személyekre hivatkozásokhoz.

Természetes módon kínálja magát számos azonossági megszorítás megfogalmazása. Alább magyarázattal adjuk meg valamennyi olyan szóba jöhető azonossági megszorítás definícióját, amelyeket a genealogy elem deklarációjában kell elhelyezni:

<xs:element name="genealogy">
    ...
    <xs:key name="person-key">
        <xs:selector xpath="person"/>
        <xs:field xpath="@id"/>
    </xs:key>
    <xs:key name="family-key">
        <xs:selector xpath="family"/>
        <xs:field xpath="husband/@ref"/>
        <xs:field xpath="wife/@ref"/>
    </xs:key>
    <xs:keyref name="person-ref" refer="person-key">
        <xs:selector xpath="family/*"/>
        <xs:field xpath="@ref"/>
    </xs:keyref>
    <xs:key name="alt-family-key">
        <xs:selector xpath="family/child"/>
        <xs:field xpath="@ref"/>
    </xs:key>
</xs:element>

1

A person-key azonossági megszorítás szemléletesen azt fejezi ki, hogy minden személyhez egyedi azonosító tartozik, amelyet a person elem id tulajdonsága szolgáltat.

2

A family-key azonossági megszorítás szemléletesen azt fejezi ki, hogy ugyanaz a két személy legfeljebb egy családi kapcsolatban adható meg férjként és feleségként. (A family elemek husband és wife elemgyermekeinek ref tulajdonságának értékei azonosítóként szolgálnak a family elemekhez.)

3

A person-ref azonossági megszorítás szemléletesen azt fejezi ki, hogy családi kapcsolatokban a genealogy elemben előforduló személyekre kell hivatkozni. (A family elemek elemgyermekeinek ref tulajdonságának értékeként valamely person elem id tulajdonságának értékét kötelező megadni.)

2

Az alt-family-key azonossági megszorítás szemléletesen azt fejezi ki, hogy egy személy legfeljebb egy családi kapcsolatban adható meg gyermekként. (A family elemek minden egyes child elemgyermekéhez tartozó ref tulajdonság értéke azonosítóként szolgál a family elemekhez.)

Végül fejezzük ki azt a követelményt, hogy a családi kapcsolatokban különböző személyek kell hogy szerepeljenek! Ehhez a family elem deklarációját az alábbiak szerint szükséges módosítani:

<xs:element name="family">
    ...
    <xs:key name="distinct-family-members">
        <xs:selector xpath="*"/>
        <xs:field xpath="@ref"/>
    </xs:key>
</xs:element>

A fenti azonossági megszorítás azt fejezi ki, hogy minden family elemben különböznek egymástól az elemgyermekek – azaz a gyermekként megengedett husband, wife és child elemek – ref tulajdonságának értékeként megjelenő nemnegatív egész értékek.


5.6. példa - A unique azonossági megszorítás

Tekintsük az alábbi elemdeklarációkat:

<xs:element name="books">
    <xs:complexType>
        <xs:sequence>
            <xs:element ref="book" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>
    <xs:unique name="book-key">
        <xs:selector xpath="book"/>
        <xs:field xpath="isbn"/>
    </xs:unique>
</xs:element>

<xs:element name="book">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="author" type="xs:string"/>
            <xs:element name="title" type="xs:string"/>
            <xs:element name="isbn" minOccurs="0" maxOccurs="1" nillable="true">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:pattern value="[0-9]{13}"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>
</xs:element>

A books elem egy lehetséges előfordulása például:

<books xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<book>
        <author>Mihail Bulgakov</author>
        <title>A Mester és Margarita</title>
        <isbn>9789630787208</isbn>
    </book>
    <book>
        <author>George  Orwell</author>
        <title>1984</title>
        <isbn>9789630788120</isbn>
    </book>
    <book>
        <author>Umberto Eco</author>
        <title>A rózsa neve</title>	
        <isbn xsi:nil="true"/>
    </book>
    <book>
        <author>Bram Stoker</author>
        <title>Drakula</title>
    </book>
    <book>
        <author>Steven Saylor</author>
        <title>Egy gladiátor csak egyszer hal meg</title>
    </book>
</books>

A fenti sémában és példában is jól látható, hogy a könyvek ISBN számát nem kötelező megadni, hiányuk jelezhető az isbn elem elhagyásával és nil értékkel is.

A books elem deklarációjában adott azonossági megszorítás azt jelenti, hogy a book elemek isbn elemgyermekeiben tartalmazott ISBN-számok nem lehetnek azonosak. A key azonossági megszorítással ellentétben azonban a unique megengedi az isbn elemek elhagyását és tartalom nélküliként megadását az xsi:nil tulajdonsággal.


Feladatok

5.7. példa -

Tekintsük az alábbi sémadokumentumot, amely determinisztikus véges állapotú atomaták ábrázolását teszi lehetővé XML-ben:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:element name="dfa">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="symbols"/>
                <xs:element ref="states"/>
                <xs:element name="start-state" type="xs:token"/>
                <xs:element ref="transition-function"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="symbols">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="symbol" type="xs:token" maxOccurs="unbounded"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="states">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="state" maxOccurs="unbounded">
                    <xs:complexType>
                        <xs:simpleContent>
                            <xs:extension base="xs:token">
                                <xs:attribute name="accept" type="xs:boolean" use="optional" default="false"/>
                            </xs:extension>
                        </xs:simpleContent>
                    </xs:complexType>    
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="transition-function">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="transition" minOccurs="0" maxOccurs="unbounded">
                    <xs:complexType>
                        <xs:attribute name="current-state" type="xs:token" use="required"/>
                        <xs:attribute name="current-symbol" type="xs:token" use="required"/>
                        <xs:attribute name="next-state" type="xs:token" use="required"/>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

</xs:schema>

A dfa elem egy lehetséges előfordulása például az alábbi:

<dfa>
    <symbols>
        <symbol>0</symbol>
        <symbol>1</symbol>
    </symbols>
    <states>
        <state accept="true">Q_1</state>
        <state>Q_2</state>
    </states>
    <start-state>Q_1</start-state>
    <transition-function>
        <transition current-state="Q_1" ="0" next-state="Q_1"/>
        <transition current-state="Q_1" current-symbol="1" next-state="Q_2"/>
        <transition current-state="Q_2" current-symbol="0" next-state="Q_2"/>
        <transition current-state="Q_2" current-symbol="1" next-state="Q_1"/>
    </transition-function>
</dfa>

Az elemek jelentése az alábbi:

  • A symbol elemek az ábécé szimbólumait sorolják fel, minden elem egy szimbólumot tartalmaz.

  • A state elemek az állapotokat sorolják fel, minden elem egy állapotot tartalmaz. Ha egy elem esetén az accept tulajdonság értéke true, akkor az állapot elfogadó állapot.

  • A start-state elem a kezdőállapotot tartalmazza.

  • A transition elemek határozzák meg az állapotátmeneteket: a current-symbol tulajdonság értékeként adott szimbólumot beolvasva az automata a current-state tulajdonság értékeként megjelenő állapotból a next-state tulajdonsággal adott állapotba megy át.

Adjuk hozzá a sémához az alábbi követelményeket kifejező azonossági megszorításokat:

  1. A symbol elemekben különböző szimbólumok megadása kötelező.

  2. A state elemekben különböző állapotok megadása kötelező.

  3. A start-state elemben, valamint a current-state és next-state tulajdonságok értékeként egy state elemben előforduló állapot megadása kötelező.

  4. A current-symbol tulajdonság értékeként egy symbol elemben előforduló szimbólum megadása kötelező.

  5. A transition elemek egy állapothoz és egy szimbólumhoz egy állapotot rendelő függvényt határozzanak meg. Ez azt jelenti, hogy nem fordulhatnak elő olyan transition elemek, amelyek current-state és current-symbol tulajdonságainak értéke megegyezik.


6. fejezet - Névterek

Bevezetés

A DTD egy komoly korlátja, hogy nem biztosít megfelelő támogatást az XML névterekhez, amelyek szinte minden modern XML alkalmazásban megjelennek. Az XML Schema eszköztára már kényelmesen teszi lehetővé XML névterek használatát, ezt egy példával szemléltetve mutatja be a fejezet.

Névterek használata

Példaként egy olyan, elvégzendő feladatok leírásához készített sémát tekintünk, amelynek kiindulási, névtereket nem használó változatát alább adjuk meg.

6.1. példa - Tennivalók leírásához készített séma névtér használata nélkül

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    elementFormDefault="unqualified"
    attributeFormDefault="unqualified">

    <xs:simpleType name="priority">
        <xs:restriction base="xs:token">
            <xs:enumeration value="low"/>
            <xs:enumeration value="normal"/>
            <xs:enumeration value="high"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:complexType name="taskType">
        <xs:sequence>
            <xs:element name="created" type="xs:dateTime"/>
            <xs:element name="priority" type="priority"/>
            <xs:element name="description" type="xs:string"/>
            <xs:element name="expiryDate" type="xs:date" minOccurs="0"/>
            <xs:element name="closed" type="xs:dateTime" minOccurs="0"/>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="identifiableTaskType">
        <xs:complexContent>
            <xs:extension base="taskType">
                <xs:attribute name="id" use="required"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:element name="task" type="identifiableTaskType"/>

    <xs:element name="taskList">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="task" minOccurs="0" maxOccurs="unbounded"/> 
            </xs:sequence>
        </xs:complexType>
        <xs:key name="task-key">
            <xs:selector xpath="task"/>
            <xs:field xpath="@id"/>
        </xs:key>
    </xs:element>

</xs:schema>

A sémában deklarált elemek használatát az alábbi dokumentum szemlélteti:

<?xml version="1.0"?>
<taskList>
    <task id="784212">
        <created>2011-05-02T12:00:00</created>
        <priority>low</priority>
        <description></description>
        <closed>2011-05-03T09:13:00</closed>
    </task>
    <task id="784213">
        <created>2011-05-07T11:43:00</created>
        <priority>high</priority>
        <description>Konferencia jelentkezés</description>
        <expiryDate>2011-06-01</expiryDate>
        <closed>2011-05-23T14:07:00</closed>
    </task>
    <task id="784214">
        <created>2011-05-09T08:01:00</created>
        <priority>normal</priority>
        <description></description>
    </task>
</taskList>


A példákban gyökérelemként megjelenő taskList elem a task elemekben egy-egy feladat leírását tartalmazza. Egy feladatról a következőket tároljuk:

  • a created elemben rögzítésének idejét,

  • a priority elemben a fontosságát,

  • a description elemben a leírását,

  • az opcionális expiryDate elemben a kitűzött határidőt,

  • az opcionális closed elemben a teljesítés idejét.

A taskList elemben előforduló minden task elemhez kötelező továbbá egy egyedi azonosító megadása az id tulajdonsággal.

A következő példákban azt mutatjuk meg, hogy hogyan lehet a fenti sémában cél-névteret használni. Válasszuk sémánk cél-névterének azonosításához a http://example/tasklist URI-t.

Négy különböző, alapvetően a lokálisan deklarált elemek és tulajdonságok használatában eltérő megoldás jöhet szóba, amelyek közül a schema elem elementFormDefault és attributeFormDefault tulajdonsága révén válaszhatunk. Minden esetben a schema elem targetNamespace tulajdonságának értékeként adjuk meg a cél-névteret.

Az elementFormDefault és az attributeFormDefault tulajdonság két lehetséges értéke qualified és unqualified. (Az alapértelmezés mindkét tulajdonságnál unqualified.) Ha az elementFormDefault (attributeFormDefault) tulajdonság értéke qualified, akkor a sémában lokálisan deklarált elemek (tulajdonságok) nevei a cél-névtérbe tartoznak, qualified esetén pedig nem tartoznak névtérbe. A felső szintű sémakomponensek nevei mindig a cél-névtérbe tartoznak. Ha egy, a cél-névtérbe tartozó név szerepel egy hivatkozásban, akkor ábrázolásához minden esetben egy megfelelő minősített név használata kötelező.

6.2. példa - Tennivalók leírásához készített séma cél-névtérrel (1. változat)

Ha az elementFormDefault tulajdonság értéke qualified, az attributeFormDefault tulajdonságé pedig unqualified, akkor a sémát a következő módon adhatjuk meg:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    elementFormDefault="qualified"
    attributeFormDefault="unqualified"
    targetNamespace="http://example/tasklist" xmlns:t="http://example/tasklist">

    <xs:simpleType name="priority">
        <xs:restriction base="xs:token">
            <xs:enumeration value="low"/>
            <xs:enumeration value="normal"/>
            <xs:enumeration value="high"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:complexType name="taskType">
        <xs:sequence>
            <xs:element name="created" type="xs:dateTime"/>
            <xs:element name="priority" type="t:priority"/>
            <xs:element name="description" type="xs:string"/>
            <xs:element name="expiryDate" type="xs:date" minOccurs="0"/>
            <xs:element name="closed" type="xs:dateTime" minOccurs="0"/>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="identifiableTaskType">
        <xs:complexContent>
            <xs:extension base="t:taskType">
                <xs:attribute name="id" use="required"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:element name="task" type="t:identifiableTaskType"/>

    <xs:element name="taskList">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="t:task" minOccurs="0" maxOccurs="unbounded"/> 
            </xs:sequence>
        </xs:complexType>
        <xs:key name="task-key">
            <xs:selector xpath="t:task"/>
            <xs:field xpath="@id"/>
        </xs:key>
    </xs:element>

</xs:schema>

A cél-névtér nélküli változathoz képest a targetNamespace, elementFormDefault és attributeFormDefault tulajdonságok megjelenésén kívül további változások is történtek. A schema elemen egy névtér-deklarációban a http://example/tasklist névtér névhez kötöttük hozzá a t előtagot, amelyet a cél-névtérben lévő nevek minősítéséhez fogunk használni.

Ha egy hivatkozásban egy olyan név fordul elő, amely a séma cél-névterébe tartozik, megfelelő minősített név használata kötelező. Ez azt jelenti, hogy például a priority elem deklarációjában a priority típus nevét t:priority módon kell megadni:

<xs:element name="priority" type="t:priority"/>

Hasonló módon hivatkozunk az identifiableTaskType típus definíciójában az alaptípusra (t:taskType), a task elem deklarációjában az identifiableTaskType típusra (t:identifiableTaskType), a taskList elem típusdefiníciójában és azonossági megszorításában a task elemre (t:task). Figyeljük meg, hogy az azonossági megszorításban azonban nem használunk előtagot az id tulajdonságra való hivatkozásban:

<xs:field xpath="@id"/>

Ennek oka az, hogy a tulajdonság neve az attributeFormDefault tulajdonság miatt nem tartozik a cél-névtérbe.

A példányt is megfelelően módosítanunk kell, alább a dokumentumban is a t előtagot kötöttük hozzá a http://example/tasklist URI-hoz:

<?xml version="1.0"?>
<t:taskList xmlns:t="http://example/tasklist">
    <t:task id="784212">
        <t:created>2011-05-02T12:00:00</t:created>
        <t:priority>low</t:priority>
        <t:description></t:description>
        <t:closed>2011-05-03T09:13:00</t:closed>
    </t:task>
    <t:task id="784213">
        <t:created>2011-05-07T11:43:00</t:created>
        <t:priority>high</t:priority>
        <t:description>Konferencia jelentkezés</t:description>
        <t:expiryDate>2011-06-01</t:expiryDate>
        <t:closed>2011-05-23T14:07:00</t:closed>
    </t:task>
    <t:task id="784214">
        <t:created>2011-05-09T08:01:00</t:created>
        <t:priority>normal</t:priority>
        <t:description></t:description>
    </t:task>
</t:taskList>

Használhatunk alapértelmezett névtér-deklarációt is, ekkor a dokumentum a következő alakot ölti:

<?xml version="1.0"?>
<taskList xmlns="http://example/tasklist">
    <task id="784212">
        <created>2011-05-02T12:00:00</created>
        <priority>low</priority>
        <description></description>
        <closed>2011-05-03T09:13:00</closed>
    </task>
    <task id="784213">
        <created>2011-05-07T11:43:00</created>
        <priority>high</priority>
        <description>Konferencia jelentkezés</description>
        <expiryDate>2011-06-01</expiryDate>
        <closed>2011-05-23T14:07:00</closed>
    </task>
    <task id="784214">
        <created>2011-05-09T08:01:00</created>
        <priority>normal</priority>
        <description></description>
    </task>
</taskList>


6.3. példa - Tennivalók leírásához készített séma cél-névtérrel (2. változat)

Ha a 6.2. példa - Tennivalók leírásához készített séma cél-névtérrel (1. változat) sémájában az elementFormDefault tulajdonság értékét unqualified-ra módosítjuk, akkor a séma többi komponense változatlan maradhat. Mivel a sémában lokálisan deklarált elemek nevei nem tartoznak névtérbe, a példány a következőképpen módosítandó:

<?xml version="1.0"?>
<t:taskList xmlns:t="http://example/tasklist">
    <t:task id="784212">
        <created>2011-05-02T12:00:00</created>
        <priority>low</priority>
        <description></description>
        <closed>2011-05-03T09:13:00</closed>
    </t:task>
    <t:task id="784213">
        <created>2011-05-07T11:43:00</created>
        <priority>high</priority>
        <description>Konferencia jelentkezés</description>
        <expiryDate>2011-06-01</expiryDate>
        <closed>2011-05-23T14:07:00</closed>
    </t:task>
    <t:task id="784214">
        <created>2011-05-09T08:01:00</created>
        <priority>normal</priority>
        <description></description>
    </t:task>
</t:taskList>


6.4. példa - Tennivalók leírásához készített séma cél-névtérrel (3. változat)

Ha az elementFormDefault és az attributeFormDefault tulajdonság értékeként qualified jelenik meg, akkor a 6.2. példa - Tennivalók leírásához készített séma cél-névtérrel (1. változat) sémájában az azonossági megszorítást módosítani szükséges. Mivel az id tulajdonság neve a cél-névtérbe tartozik, a tulajdonság nevét hivatkozásban a t előtaggal kell minősíteni:

<xs:element name="taskList">
    ...
    <xs:key name="task-key">
        <xs:selector xpath="t:task"/>
        <xs:field xpath="@t:id"/>
    </xs:key>
</xs:element>

Ekkor a példányt az alábbi módon kell megadni:

<?xml version="1.0"?>
<t:taskList xmlns:t="http://example/tasklist">
    <t:task t:id="784212">
        <t:created>2011-05-02T12:00:00</t:created>
        <t:priority>low</t:priority>
        <t:description></t:description>
        <t:closed>2011-05-03T09:13:00</t:closed>
    </t:task>
    <t:task t:id="784213">
        <t:created>2011-05-07T11:43:00</t:created>
        <t:priority>high</t:priority>
        <t:description>Konferencia jelentkezés</t:description>
        <t:expiryDate>2011-06-01</t:expiryDate>
        <t:closed>2011-05-23T14:07:00</t:closed>
    </t:task>
    <t:task t:id="784214">
        <t:created>2011-05-09T08:01:00</t:created>
        <t:priority>normal</t:priority>
        <t:description></t:description>
    </t:task>
</t:taskList>


7. fejezet - További lehetőségek

Bevezetés

Ebben a szakaszban az XML Schema néhány további, korábban nem tárgyalt lehetőségét mutatjuk be.

Hiányzó értékek

Információ rendelkezésre nem állását kifejezheti a példányokban elemek és tulajdonságok hiánya.

7.1. példa - Hiányzó érték kifejezése elem hiányával

Deklaráljunk például egy személy nevét és születési dátumát tartalmazó person elemet az alábbi módon:

<xs:element name="person">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="name" type="xs:string"/>
            <xs:element name="birthdate" type="xs:date" minOccurs="0" maxOccurs="1"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>

Ha egy személy születési dátuma ismeretlen, akkor ezt a birthdate elem hiányával fejezhetjük ki a példányokban:

<person>
    <name>Homer Simpson</name>
</person>


Az XML Schema egy olyan mechanizmust is biztosít azonban, amellyel elemek esetében a hiány explicit módon jelezhető. A mechanizmus lehetővé teszi tartalom nélküli elemek érvényesként történő elfogadását olyan esetekben is, amelyekben a típusdefiníciója ezt egyébként nem engedné meg.

Elemdeklarációkban az element elemhez adható meg a logikai típusú nillable tulajdonság, amelynek alapértelmezett értéke false. Ha a nillable tulajdonság értéke true, akkor az elem a példányokban előfordulhat tartalom nélküliként is, függetlenül attól, hogy ezt a típusdefiníciója megengedi-e.

Példányokban a logikai típusú xsi:nil tulajdonság megadásával jelezhető a hiány. Ha egy elem xsi:nil tulajdonságának értéke true, akkor nem tartalmazhat gyermekként karakteres adatot és elemeket sem (tulajdonságai viszont lehetnek). Kizárólag akkor adható meg azonban a tulajdonság egy elemhez, ha a deklarációjában a nillable tulajdonság értéke true.

7.2. példa - Hiányzó érték kifejezése az xsi:nil tulajdonsággal

Így módosíthatjuk a fentieknek megfelelően az előző példa deklarációját:

<xs:element name="person">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="name" type="xs:string"/>
            <xs:element name="birthdate" type="xs:date" nillable="true"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>

A példányokban az érvényességhez kötelező a birthdate elem megadása, azonban az xsi:nil tulajdonsággal jelezhetjük az információ hiányát:

<person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <name>Homer Simpson</name>
    <birthdate xsi:nil="true"/>
</person>


Például relációs adatbáziskezelő rendszerekből származó adatok esetén ezt a megoldást ajánlott választani null érték ábrázolásához.

Kommentárok

Sémadokumentumokban felső szinten bárhol előfordulhat az annotation elem, amely a legtöbb sémaelem tartalmának elején is megengedett (az annotation, appinfo és documentation elemekben nem áll rendelkezésre). Az annotation elemben kétféle elem szerepelhet tetszőleges számban és sorrendben:

  • emberi fogyasztásra szánt dokumentációt tartalmazó documentation elem,

  • stíluslapok és egyéb alkalmazások számára információkat tartalmazó appinfo elem.

A annotation elemekben megadott elemeket az érvényesítés során figyelmen kívül kell hagyni.

A documentation elemekhez az xml:lang tulajdonsággal ajánlott megadni a tartalomként megjelenő szöveg nyelvét. A documentation és appinfo elemekhez tetszőleges olyan tulajdonság megadható, amely nem a http://www.w3.org/2001/XMLSchema URI által azonosított névtérbe tartozik, az elemek tartalmára azonban semmilyen korlátozás nem vonatkozik.

7.3. példa - A documentation elem használata

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:annotation>
        <xs:documentation xml:lang="en">
            This schema defines datatypes for handling ISBN numbers.
        </xs:documentation>
        <xs:documentation xml:lang="hu">
            A séma ISBN-számok kezeléséhez definiál adattípusokat.
        </xs:documentation>
    </xs:annotation>

    <xs:annotation>
        <xs:documentation xml:lang="en">
            This work is licensed under the
            Creative Commons Attribution-ShareAlike License.
            To view a copy of this license, visit
            http://creativecommons.org/licenses/by-sa/3.0/.
        </xs:documentation>
    </xs:annotation>

    <xs:simpleType name="isbn13">
        <xs:annotation>
            <xs:documentation xml:lang="en">
                Datatype for 13-digit ISBN numbers
            </xs:documentation>
            <xs:documentation xml:lang="hu">
                Adattípus 13 jegyű ISBN-számokhoz
            </xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:string">
            <xs:pattern value="\d{13}"/>
        </xs:restriction>
    </xs:simpleType>
    ...

</xs:schema>


7.4. példa - Az appinfo elem használata

A JAXB [JSR 222] egy Java keretrendszer, amely Java osztályok és XML sémák közötti leképezés megvalósítására szolgál. Egy olyan XML feldolgozó API-t biztosít, amely a programozó számára transzparens módon teszi lehetővé az átjárást objektumok és XML dokumentumok között. Segítségével automatikusan állíthatóak elő objektumok XML reprezentációi, valamint nyerhetők vissza az XML dokumentumokból a megfelelő objektumok.

A programnyelvi és XML séma konstrukciók egymásnak történő megfeleltetése testreszabható olyan deklarációkkal, amelyeket a sémákban appinfo elemekben elhelyezett XML elemek formájában kell megadni.

A keretrendszer része olyan sémafordítónak nevezett kódgenerátor eszköz, amely képes XML sémákból a megfelelő, a példányokat tartalmát tárolni képes Java osztályok előállítására. Az appinfo elemekben elhelyezett deklarációkkal vezérelhető a sémafordító működése is.

Alább látható egy példa JAXB deklaráció használatára:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.0">

    <xs:annotation>
        <xs:appinfo>
            <jaxb:schemaBindings>
                <jaxb:package name="myPackage"/>
            </jaxb:schemaBindings>
        </xs:appinfo>
    </xs:annotation>
    ...

</xs:schema>

A jaxb:schemaBindings elemben megadott jaxb:package elem egy olyan deklaráció, amely a sémának megfelelő osztályok csomagjának nevét adja meg. A sémafordító a kódgenerálás során automatikusan a deklarációban adott csomagban helyezi el az előállított osztályokat.


8. fejezet - Példányok

Bevezetés

Az XML Schema definiál néhány olyan tulajdonságot, amelyek az érvényesítendő XML dokumentumokban fordulhatnak elő. Ezek a tulajdonságok egy olyan névtérben vannak, amelyet a http://www.w3.org/2001/XMLSchema-instance URI azonosít, és amelyhez általában az xsi névtér előtagot használjuk. A következő tulajdonságok tartoznak a névtérbe:

  • xsi:type

  • xsi:nil

  • xsi:schemaLocation és xsi:noNamespaceSchemaLocation

A fenti négy tulajdonságot a sémákban nem szükséges és tilos deklarálni, minden sémafeldolgozó számára beépítetten rendelkezésre állnak a megfelelő deklarációik.

xsi:type

A QName típusú xsi:type tulajdonság az elemek típusának explicit jelzésére szolgál. Értéke az elem érvényesítéséhez használandó típusdefiníciót azonosító minősített név.

xsi:nil

Az XML Schema lehetőséget ad tartalom nélküli elemek érvényesként történő elfogadására olyan esetekben is, amelyekben egyébként a típusdefiníció ezt nem engedné meg. Ehhez az elemekhez az xsi:nil logikai típusú tulajdonságot true értékkel kell megadni. A tulajdonság használatát Hiányzó értékek című szakaszban tárgyaljuk részletesen.

9. fejezet - Esettanulmány

Bevezetés

Ebben a fejezetben egy olyan komplex XML sémát ismertetünk esettanulmányként, amelyben haladó szinten használjuk a szabvány lehetőségeit. Az esettanulmány példaként kíván szolgálni arra, hogy miként lehet elegáns módon és hatékonyan megvalósítani egy XML sémát egy gyakorlati problémára.

Programozási nyelv szintaxisának leírása XML sémával

XML szintaxisú programozási nyelvek

Alább egy XML sémát mutatunk be, amely egy egyszerű programozási nyelv szintaxisát írja le. Az iparban ténylegesen használnak olyan programozási nyelveket, amelyek szintaxisként az XML-t használják. Számos előnye van az XML szintaxisú programozási nyelveknek:

  • Mivel a szintaxist XML sémával írjuk le, a programok szintaktikai ellenőrzése XML dokumentum érvényesítést jelent, amelyet egy érvényesítő XML feldolgozó képes elvégezni, nincs szükség speciális elemzőre.

  • A séma a szintaxis teljes és abszolút pontos leírását adja, alkalmazások széles köre használhatja fel különféle célokra.

  • Névterek használata révén a programozási nyelv rugalmasan terjeszthető ki akár a séma módosítása nélkül.

  • Egy XML szintaxisú programozási nyelv tekinthető olyan meta-programozási nyelvnek, amelynek programjaiból különböző programozási nyelvek ekvivalens programjait lehet előállítani.

Fontos azt hangsúlyozni, hogy az XML ebben a megközelítésben csupán egy szintaxisleíró eszköz, a szemantikával – beleértve ebbe a programok végrehajtását – nem foglalkozunk. Egy lehetőség a programok végrehajtására azok átalakítása más programozási nyelvek programjaivá – például C++ vagy Java programokká –, amely történhet XSLT stíluslapok révén.

Egy játék programozási nyelv

Mi csupán egy olyan játék programozási nyelvet tekintünk, amely mindössze néhány elemi utasításból áll, nem teszi lehetővé szubrutinok használatát sem. Egy olyan strukturálatlan programozási nyelv, amely lehetőségeit tekintve a korai programozási nyelvek szintjén marad. Elegendően egyszerű tehát ahhoz, hogy alig száz sorban alkossuk meg a szintaxist leíró XML sémát, amely viszont már elég összetett, hogy esettanulmányként szolgáljon.

Programozási nyelvünkben az utasításokat XML elemek ábrázolják. Minden program utasítások egy olyan sorozata, amelyeket egy program elem tartalmaz:

<program>utasítás(ok)</program>

A következő szakaszokban tekintjük át részletesen a rendelkezésre álló utasításokat.

9.1. példa - Egy program XML-ben

Egy példa kis programozási nyelvünk szintaxisának bemutatására:

<?xml version="1.0"?>
<!-- legnagyobb közös osztó meghatározása euklideszi algoritmussal -->
<program>
    <assign var="a" expr="1234"/>
    <assign var="b" expr="563"/>
    <while cond="a != b">
        <if cond="a &gt; b">
            <assign var="a" expr="a - b"/>
        <else/>
            <assign var="b" expr="b - a"/>
        </if>
    </while>
    <println>A legnagyobb közös osztó: <value expr="a"/></println>
</program>

Értékadás.  Az értékadó utasítást egy

<assign var="név" expr="kifejezés"/>

üreselem ábrázolja, ahol a var és expr tulajdonságokkal adható meg a változó neve és a változó értékét szolgáltató kifejezés. A var tulajdonság értékeként például a beépített Name adattípus literáljait követelhetjünk meg, az expr tulajdonság értékére azonban nem írunk elő semmiféle megszorítást (egy tetszőleges karakterlánc). Az egyszerűség kedvéért feltételezhetjük, hogy minden változó egész típusú. Mivel a változók értékét szolgáltató kifejezésekkel szemben a sémában semmiféle megszorítást nem támasztunk, élhetnénk akár azzal a feltevéssel is, hogy a kifejezés kiértékelésének eredménye határozza meg a változó típusát.

Kilépés a progamból.  A program végrehajtásának befejezését eredményező utasítást az <exit/> üreselem ábrázolja.

Szöveg a kimenetre történő írása.  Két utasítást is biztosít a nyelv adott szöveg a kimenetre történő kiírására, amelyeket az alábbi elemek ábrázolnak:

<print>szöveg</print>
<println>szöveg</println>

Mindkét elemnél megengedjük a tartalmazott szövegben tetszőleges számú olyan

<value expr="kifejezés"/>

üreselem előfordulását, amely az expr tulajdonsággal adott kifejezés értékének a szövegbe történő beillesztésére szolgál (a tulajdonság értéke tetszőleges karakterlánc lehet).

Kezdőfeltételes ciklus.  A kezdőfeltételes ciklust a

<while cond="kifejezés">utasítás(ok)</while>

elem ábrázolja, ahol a cond tulajdonság hordozza a feltételt, amely egy tetszőleges karakterlánc lehet. Az elem tartalmaként kell megadni a ciklusmagot alkotó utasításokat. Kizárólag ebben az utasításban megengedjük <break/> és <continue/> utasítások előfordulását is. Ez a két utasítás nem szerepelhet cikluson kívül!

Feltételes elágaztatás.  Mind közül a feltételes elágaztatás a legbonyolultabb utasítás, amelyet az alábbi elem ábrázol, ahol a cond tulajdonságok értéke egy tetszőleges karakterlánc:

<if cond="kifejezés">
    utasítás(ok)
[<elseif cond="kifejezés"/>
    utasítás(ok)]...
[<else/>
    utasítás(ok)]
</if>

A fenti leírás azt jelenti, hogy az if elemben az utasítások között meg lehet adni tetszőleges számú elseif üreselemet, amelyeket egy opcionális else üreselem is követhet. Ez a két elem azonban kizárólag az if elemben fordulhat elő, azon kívül nem engedélyezett a használatuk!

[Megjegyzés]Megjegyzés

Kézenfekvő módon kínálja magát a feltételes elágaztató utasításhoz a következő szintaxis:

<if cond="kifejezés">
    utasítás(ok)
[<else/>
    utasítás(ok)]
</if>

Az else-ágon azonban gyakran egy további if utasítás jelenik meg, így az alábbi szerkezetet kaphatjuk:

<if cond="kifejezés">
    utasítás(ok)
    <else/>
    <if cond="kifejezés">
        utasítás(ok)
        <else/>
        <if cond="kifejezés">
            utasítás(ok)
            <else/>
            ...
        </if>
    </if>
</if>

Ennek elkerülésére használjuk az elsőként megadott szintaxist a feltételes elágaztató utasításhoz, amely jobban átlátható szerkezetet eredményez, ráadásul kevesebb gépelést is igényel.

XML séma

A programozási nyelvhez készített XML sémát az C. függelék - Dokumentumok az Esettanulmány című fejezethez tartalmazza. Ebben a szakaszban részletesen megvizsgáljuk a sémát, sorban végighaladva annak valamennyi komponensén. A sémából kiemelt sorok mellett azok eredeti sorszámát tüntetjük fel.

Megjegyezzük, hogy a sémában globális elemekkel adjuk meg azokat az utasításokat, amelyek előfordulhatnak a program elem közvetlen gyermekeiként (nevezzük ezeket a továbbiakban felső szintű utasításoknak). Ez maga után vonja azt, hogy a példányokban bármely felső szintű utasítás lehet gyökérelem. Azért választottuk mégis ezt a megoldást, mert a séma így jobban átlátható. Ráadásul így használhatunk absztrakt elemeket is (ne feledjük, hogy csak globális elemek lehetnek absztrakt elemek).

Lokális deklarációkat azokhoz az utasításokhoz használunk, amelyek csak más utasításokban megengedettek – ilyenek a break, continue, else, elseif és value elemek –, valamint az if elemhez.

A séma elején a cond és expr tulajdonságokat deklaráljuk, amelyeket több utasításhoz is fel fogunk használni:

    <xs:attribute name="cond" type="xs:string"/>
    <xs:attribute name="expr" type="xs:string"/>

Ezt néhány komplex típus definíciója követi:

    <xs:complexType name="emptyStatement"/>

    <xs:complexType name="emptyStatementWithExpr">
        <xs:attribute ref="expr" use="required"/>
    </xs:complexType>

    <xs:complexType name="emptyStatementWithCond">
        <xs:attribute ref="cond" use="required"/>
    </xs:complexType>

Az emptyStatement típust azokhoz az utasításokhoz használjuk, amelyeket olyan üreselemek ábrázolnak, amelyeknek nincsenek attribútumai sem (break, continue, else). Az emptyStatementWithExpr típus a value elem típusa, az emptyStatementWithCond pedig az elseif elemé.

Az assign és exit elemek deklarációi értelemszerűek:

    <xs:element name="assign">
        <xs:complexType>
            <xs:attribute name="var" type="xs:NCName" use="required"/>
            <xs:attribute ref="expr" use="required"/>
        </xs:complexType>
    </xs:element>

    <xs:element name="exit" type="emptyStatement"/>

A print és println elemeket azonos módon kell használni, ráadásul ahol az egyik megengedett, ott használható a másik is, ezért ezekhez deklaráltunk egy olyan absztrakt elemet, amelyet mindkét elem helyettesíthet:

    <xs:element name="printOrPrintln" abstract="true">
        <xs:complexType mixed="true">
            <xs:sequence>
                <xs:element name="value" type="emptyStatementWithExpr" minOccurs="0" maxOccurs="unbounded"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="print" substitutionGroup="printOrPrintln"/>

    <xs:element name="println" substitutionGroup="printOrPrintln"/>

A továbbiakban csak az absztrakt elemmel fogunk dolgozni.

A soron következő sémakomponensek megértéséhez fontos annak felismerése, hogy a legnagyobb kihívást az if elem megfelelő deklarálása jelenti. A csak a while elemben megengedett break és continue utasítások miatt igényel ez az elem a többi utasításhoz képest több törődést. Az if elemet valójában kétszer, némileg eltérő módon kell deklarálni (emiatt szükségesek lokális deklarációk): felső szintű előfordulásai nem tartalmazhatják a break és continue elemeket, while elemben történő előfordulásai azonban igen.

Az alábbi modellcsoport-definícióban egy olyan, topLevelStatement nevű csoportot hozunk létre, amely alternatívaként tartalmazza a felső szintű utasítások elemeit:

    <xs:group name="topLevelStatement">
        <xs:choice>
            <xs:element ref="assign"/>
            <xs:element ref="exit"/>
            <xs:element name="if" type="topLevelIf"/>
            <xs:element ref="printOrPrintln"/>
            <xs:element ref="while"/>
        </xs:choice>
    </xs:group>

Figyeljük meg, hogy az if elemet lokálisan deklaráljuk topLevelIf típusúként. A csoportot a program és a felső szintű if elem típusának definiálásához használjuk majd.

Az innerStatement csoport a felső szintű utasítások elemeit valamint a break és continue elemeket is megengedi:

    <xs:group name="innerStatement">
        <xs:choice>
            <xs:element ref="assign"/>
            <xs:element name="break" type="emptyStatement"/>
            <xs:element name="continue" type="emptyStatement"/>
            <xs:element ref="exit"/>
            <xs:element name="if" type="innerIf"/>
            <xs:element ref="printOrPrintln"/>
            <xs:element ref="while"/>
        </xs:choice>
    </xs:group>

Ebben a csoportban az if elemet innerIf típusúként deklaráljuk. Ezt a csoportot a while elem és a benne előforduló if elem típusának definiálásához használjuk.

Egy olyan komplex típust definiálunk, amely tartalomként olyan utasítások sorozatát engedi meg, amelyek előfordulhatnak a while elemben:

    <xs:complexType name="innerStatementList">
        <xs:group ref="innerStatement" minOccurs="0" maxOccurs="unbounded"/>
    </xs:complexType>

Most definiáljuk azt a komplex típust, amely tartalomként felső szintű utasítások sorozatát engedi meg, ilyen típusúként deklaráljuk a program elemet:

    <xs:complexType name="topLevelStatementList">
        <xs:complexContent>
            <xs:restriction base="innerStatementList">
                <xs:group ref="topLevelStatement" minOccurs="0" maxOccurs="unbounded"/>
            </xs:restriction>
        </xs:complexContent>
    </xs:complexType>

    <xs:element name="program" type="topLevelStatementList"/>

Figyeljük meg, hogy a topLevelStatementList típust megszorítással származtatjuk az innerStatementList komplex típusból. Ez megtehető, mivel az alaptípushoz képest szűkítjük a tartalomként megengedett elemek halmazát, kizárva a break és continue elemeket, valamint az if elem típusaként az innerIf típusból megszorítással származtatott topLevelIf típust használjuk, így az if elem használatát is korlátozzuk.

Az előbbi sémakomponensek felhasználásával az alábbi módon deklaráljuk a while elemet:

    <xs:element name="while">
        <xs:complexType>
            <xs:complexContent>
                <xs:extension base="innerStatementList">
                    <xs:attribute ref="cond" use="required"/>
                </xs:extension>
            </xs:complexContent>
        </xs:complexType>
    </xs:element>

Az elem típusának alaptípusként a innerStatementList típus szolgál, amelyet úgy terjesztenünk ki, hogy kötelezővé tesszük a ciklus feltételét hordozó cond tulajdonságot.

Mivel a felső szintű utasítások elemeit az if elem kivételével globálisan deklaráltuk, deklarálunk egy globális if elemet is, amelyet azonban nem használunk sehol máshol a sémában:

    <xs:element name="if" type="topLevelIf"/>

Így a többi felső szintű utasításhoz hasonlóan ez az elem is lehet a példányokban gyökérelem.

Végül sémánk legösszetettebb komponensei, az if elemekhez tartozó típusdefiníciók következnek. Elsőként annak az if elemnek a típusát adjuk meg, amelyet a while elemben használunk, és amely megengedi a break és continue elemeket is:

    <xs:complexType name="innerIf">
        <xs:sequence>
            <xs:choice minOccurs="0" maxOccurs="unbounded">
                <xs:group ref="innerStatement"/>
                <xs:element name="elseif" type="emptyStatementWithCond"/>
            </xs:choice>
            <xs:sequence minOccurs="0" maxOccurs="1">
                <xs:element name="else" type="emptyStatement"/>                
                <xs:group ref="innerStatement" minOccurs="0" maxOccurs="unbounded"/>
            </xs:sequence>
        </xs:sequence>
        <xs:attribute ref="cond" use="required"/>
    </xs:complexType>

Az ilyen típusú elemben tartalomként az innerStatement csoport elemei és elseif elemek fordulhatnak elő tetszőleges számban és sorrendben, amelyeket egy olyan opcionális else elem követhet, amely után ismét az innerStatement csoport elemei szerepelhetnek tetszőleges számban és sorrendben. Az elseif és else elemek lokálisan deklaráltak, mivel ezeket kizárólag itt használhatjuk. A típus kötelezőként írja elő továbbá a cond attribútum megadását.

Az előbbi típusból megszorítással származtatjuk a felső szintű if elem típusát:

    <xs:complexType name="topLevelIf">
        <xs:complexContent>
            <xs:restriction base="innerIf">
                <xs:sequence>
                    <xs:choice minOccurs="0" maxOccurs="unbounded">
                        <xs:group ref="topLevelStatement"/>
                        <xs:element name="elseif" type="emptyStatementWithCond"/>
                    </xs:choice>
                    <xs:sequence minOccurs="0" maxOccurs="1">
                        <xs:element name="else" type="emptyStatement"/>                
                        <xs:group ref="topLevelStatement" minOccurs="0" maxOccurs="unbounded"/>
                    </xs:sequence>
                </xs:sequence>
            </xs:restriction>
        </xs:complexContent>
    </xs:complexType>

Ez megtehető, mivel a tartalomként megengedett elemek halmazát szűkítjük olyan módon, hogy a innerStatement csoport helyett a topLevelStatement csoportot használjuk, amely nem engedi meg a break és continue elemeket. A cond tulajdonságot nem kell deklarálnunk, mivel a származtatás során a típus örökli az alaptípushoz deklarált tulajdonságokat.

A programok végrehajtása

Az C. függelék - Dokumentumok az Esettanulmány című fejezethez tartalmaz egy olyan XSLT stíluslapot, amely minden programot egy ekvivalens ANSI C programmá alakít, amelyet már bármely C fordítóval le lehet fordítani. A szerző honlapján a programozási nyelvhez elérhető továbbá egy olyan, Java-ban implementált interpreter, amely képes a programok közvetlen végrehajtására.

Feladatok

  1. Módosítsuk a programozási nyelv szintaxisát leíró sémát úgy, hogy minden utasításhoz megadható legyen egy egyedi azonosító az id tulajdonsággal. Ezt követően bővítsük a nyelvet egy olyan goto ugró utasítással, amellyel egy adott azonosítójú utasításra adható át a vezérlés.

  2. Követeljük meg a változókhoz típus megadását. Ehhez módosítsuk a sémát úgy, hogy a program elején minden később használni kívánt változót deklarálni legyen kötelező, amely történjen a

    <declare var="név" type="típus" expr="kifejezés"/>

    utasítással, ahol a type tulajdonság a változó típusát, az expr tulajdonság pedig a kezdőértékét szolgáltatja. Típusként használjuk a programozási nyelvekben elterjedten támogatott adattípusokat (mint például int, float, double) vagy az XML séma beépített adattípusait.

    Azonossági megszorításokkal írjuk elő, hogy adott nevű változó csak egyszer legyen deklarálható, értékadó utasítás var tulajdonságának értékeként pedig csak deklarált változó neve szerepelhessen.

  3. Tegyük lehetővé a programokban függvények definiálását. Egy lehetséges szintaxis az alábbi:

    <function name="gcd" type="xs:integer">
        <params>
            <param name="a" type="xs:integer"/>
            <param name="b" type="xs:integer"/>
        </params>
        <body>
            <while cond="a != b">
                <if cond="a &gt; b">
                    <assign var="a" expr="a - b"/>
                <else/>
                    <assign var="b" expr="b - a"/>
                </if>
            </while>
            <return expr="a"/>
        </body>
    </function>

    Feltételezhetjük, hogy a függvények minden esetben értéket adnak vissza, így a függvényhívás természetes módon használható kifejezésekben az alábbi módon:

    <assign var="c" expr="gcd(a,b)"/>

    Minden további részlet átgondolását és kidolgozását az olvasóra bízzuk (például hogy lehessen-e globális változókat használni, hol történjen a programba a belépés a végrehajtás megkezdésekor).

A. függelék - Beépített adattípusok

Beépített adattípusok azonosítása

Minden beépített adattípust egy olyan erőforrásrész-azonosítót tartalmazó URI azonosít, amelyben a bázis-URI http://www.w3.org/2001/XMLSchema, az erőforrásrész-azonosító pedig az adattípus neve. Például a boolean adattípushoz tartozó URI http://www.w3.org/2001/XMLSchema#boolean.

A beépített adattípusokat úgy tervezték, hogy önmagukban is használhatóak legyenek más XML specifikációkhoz. Ezért az adattípusok egy olyan névtérben is rendelkezésre állnak, amelyet a http://www.w3.org/2001/XMLSchema-datatypes URI azonosít. Ez olyan XML specifikációk számára szolgál bázis-URI-ként az adattípusok azonosításához, amelyek nem igénylik és támogatják az XML Schema más lehetőségeit.

Beépített primitív adattípusok

anyURI

URI hivatkozásokat reprezentáló adattípus.

Az értéktér elemei az [RFC 3986] specifikációban definiált URI-k és relatív hivatkozások, együttes nevükön URI hivatkozások. A relatív hivatkozások URI-k séma-specifikus részei vagy azok alkalmas végszeletei, amelyeket egy úgynevezett bázis-URI alapján érvényes URI-vá lehet feloldani. Míg minden URI abszolút módon, az előfordulás környezetétől függetlenül azonosít egy erőforrást, a relatív hivatkozások egy adott környezetben rövidítenek egy URI-t.

Míg URI hivatkozásokban az [RFC 3986] specifikációnak megfelelően csak az ASCII karakterek egy részhalmaza használható, az anyURI típus a literálokhoz rendelkezésre álló karakterek tekintetében megengedőbb.

A lexikális tér elemei azok a karakterláncok, amelyekre az alábbi algoritmus végrehajtása az [RFC 3986] specifikációnak megfelelő URI hivatkozást eredményez (az algoritmus egyben a lexikális tér minden eleméhez az értéktér egy elemét rendelni hozzá):

  • A karakterlánc minden olyan karakterére hajtsuk végre az alábbi lépéseket, amelyek URI hivatkozásokban nem megengedettek:

    1. Tekintsük a karaktert az UTF-8 karakterkódolásban ábrázoló oktettsorozatot!

    2. Az oktettsorozatot kódoljuk egy olyan karakterlánccal, amelyben minden oktettet %HH módon ábrázolunk, ahol HH az oktett értékét reprezentáló két hexadecimális számjegy karakter.

    3. A nem megengedett karaktert helyettesítsük az oktettsorozatot kódoló karakterlánccal.

Például a http://www.w3.org/People/Dürst/ karakterlánc esetén az algoritmus végrehajtásának eredménye a http://www.w3.org/People/D%C3%BCrst/ URI.

Érvényes literálok például:

http://www.w3.org/TR/REC-xml/
http://en.wikipedia.org/wiki/The_Beatles#History
/pub/linux/kernel/
../../../images/bullet2.png
chapter1.html#introduction
#contents
Letöltés

Az anyURI adattípusra alkalmazható korlátozó adattípus-tulajdonságok:

enumeration
length
maxLength
minLength
pattern
whiteSpace

base64Binary

Base64-kódolt bináris adatok kezelésére szolgáló adattípus. [RFC 2045] definiálja a Base64 kódolást, amellyel nyomtatható karakterekből álló ASCII karaktersorozatokká kódolható tetszőleges bináris oktettsorozat. (A kódolás 65 rögzített nyomtatható ASCII-karakter felhasználásával történik.)

Például az UTF-8 karakterkódolással ábrázolt pókszóró horoszkóp karakterlánc Base64 kódolásának eredménye a cMOza3N6w7Nyw7MgaG9yb3N6a8OzcA== ASCII karakterlánc.

Az értéktér a (kódolandó) véges oktettsorozatok, a lexikális tér pedig az ezeket kódoló karaktersorozatok halmaza.

A base64Binary adattípusra alkalmazható korlátozó adattípus-tulajdonságok:

enumeration
length
maxLength
minLength
pattern
whiteSpace

boolean

Logikai adattípus, amelynek értékterét az igaz és hamis logikai értékek, lexikális terét a true, false, 0, 1 literálok alkotják. A true és 1 literálok jelölik az igaz, a false és 0 literálok pedig a hamis logikai értéket. A kanonikus lexikális reprezentáció a true és false literálokból áll.

A boolean adattípusra alkalmazható korlátozó adattípus-tulajdonságok:

pattern
whiteSpace

date

Naptári dátumok kezeléséhez biztosítja a szabvány a date adattípust.

Az értéktér formálisan olyan, pontosan egy nap hosszúságú balról zárt és jobbról nyílt dateTime intervallumok halmaza, amelyek mindegyikének kezdőpontja egy adott nap kezdetének pillanata (00:00:00).

A lexikális tér elemei olyan évre, hónapra és napra csonkolt dateTime literálok, amelyeket opcionálisan követhet időzóna jelző.

Például az 1848-03-15 literál jelöli az 1848. március 15. dátumot.

[Megjegyzés]Megjegyzés

Különböző literálok ábrázolhatják az értéktér egy adott elemét. Például a 2004-10-28+13:00 és 2004-10-27-11:00 literáloknak megfelelő intervallum kezdőpontja 2004-10-27ZT11:00:00Z.

A kanonikus lexikális reprezentációban időzóna jelzőként csak az egyezményes koordinált világidőt (UTC) jelentő Z megengedett.

A date adattípusra alkalmazható korlátozó adattípus-tulajdonságok:

enumeration
maxExclusive
maxInclusive
minExclusive
minInclusive
pattern
whiteSpace

dateTime

Egyedi időpillanatokat ábrázoló adattípus, melynek értekei dátum-idő kombinációkként tekinthetőek.

Az értéktér elemeinek mindegyikét egy adott napot meghatározó dátum, a nap egy időpillanatát meghatározó idő, valamint egy, időzóna használatát jelző logikai érték alkotja. Ha a logikai érték igaz, akkor az idő egyezményes koordinált világidő (UTC idő), a hamis érték pedig azt jelenti, hogy nem áll rendelkezésre időzóna információ az értelmezéshez.

Megjegyezzük, hogy nincs 0. év, a kronológia kezdőpontja az első év első napja.

A lexikális tér elemei [-]ÉÉÉÉ-HH-NNThh:mm:ss[.sss][zzzzzz] formájú karakterláncok, ahol:

  • A literálok elején opcionálisan megadható - karakter időszámításunk előtti dátumot jelent.

  • ÉÉÉÉ az évet ábrázoló, legalább 4 decimális számjegy karakterből álló karaktersorozat. Négynél kevesebb számjegyű év esetén megfelelő számú vezető nulla számjegy szükséges az évszám elejére, azonban négynél hosszabb számjegysorozat elején tilos vezető nulla számjegyek használata.

  • HH a hónapot ábrázoló két decimális számjegy karakter.

  • NN a napot ábrázoló két decimális számjegy karakter.

  • hh az órát ábrázoló két decimális számjegy karakter, amelyként 24 csak akkor megengedett, ha mm és ss is 00 (ebben az esetben a literál a következő nap első időpillanatát ábrázolja).

  • mm a percet ábrázoló két decimális számjegy karakter.

  • ss a másodpercet ábrázoló két decimális számjegy karakter, amelyet opcionálisan követhet egy decimális pont karakter és tetszőleges számú, de legalább egy decimális számjegy karakter.

  • zzzzzz opcionálisan megadható, +hh:mm vagy -hh:mm vagy Z formájú időzóna jelző, amelyek közül az utóbbi az egyezményes koordinált világidőt (UTC) jelenti.

Időzóna jelzőt tartalmazó literálok értékeknek történő megfeleltetése egyezményes koordinált világidőre való konverzióval történik.

Érvényes literálok például:

2001-09-11T08:46:00-04:00 (az első repülő becsapódásának pillanata a szeptember 11-ei terrortámadások napján)
1969-07-16T13:32:00Z (az Apollo-11 fellövésének pillanata)
0001-01-01T00:00:00Z (időszámításunk kezdetének pillanata)
2011-06-15T21:22:00+01:00 (a 2011 nyarán hazánkban megfigyelhető teljes holdfogyatkozás kezdetének pillanata)

A kanonikus lexikális reprezentáció az alábbi módon definiált:

  • Óra ábrázolásához tilos a 24 számjegyek használata.

  • Töredék másodperc használata esetén a decimális pont karaktert követő utolsó decimális számjegy karakter nem lehet 0.

  • Időzóna jelzőként csak Z megengedett.

Az értéktéren egy szigorú részbenrendezési reláció értelmezett. Időzónás értékek összehasonlítása értelemszerűen végezhető el a komponensek összehasonlításával. Jelöljön P egy időzónás értéket, Q pedig egy időzóna nélküli értéket, ekkor P és Q összehasonlítása az alábbi algoritmus alapján történik:

  1. Tételezzünk fel Q-hoz +14:00 időzónát, ha ekkor P megelőzi Q-t, akkor ez az összehasonlítás eredménye.

  2. Tételezzünk fel Q-hoz -14:00 időzónát, ha ekkor Q megelőzi P-t, akkor ez az összehasonlítás eredménye.

  3. Egyébként P és Q nem összehasonlítható.

A dateTime adattípusra alkalmazható korlátozó adattípus-tulajdonságok:

enumeration
maxExclusive
maxInclusive
minExclusive
minInclusive
pattern
whiteSpace

decimal

Decimális számok kezelésére szolgáló adattípus.

Az értéktér az alakban kifejezhető számok halmaza, ahol egész, pedig nemnegatív egész. Minden feldolgozó számára kötelező legalább 18 decimális számjegyet tartalmazó decimális számok használatának támogatása.

A lexikális tér elemei olyan decimális számjegyekből álló karakterláncok, amelyek opcionálisan tartalmazhatnak egy, a tizedesvessző helyét jelölő pont karaktert, első karakterként pedig egy előjel karaktert.

Érvényes literálok például: +42, 1000.00, 3.141593, -0.7071068

A kanonikus lexikális reprezentáció az alábbi módon definiált:

  • Kötelező a pont karakter használata, amelynek mindkét oldalán legalább egy számjegy megadása kötelező.

  • Előjelként tilos a + karakter megadása.

  • Tilos vezető és a decimális pontot követő szám végi nullák használata a következő kivételtől eltekintve: egyetlen nulla számjegy önmagában állhat a decimális pont mindkét oldalán.

A fentiek alapján például a 0 számot a 0.0 literál ábrázolja a kanonikus lexikális reprezentációban.

Az értéktéren egy szigorú teljes rendezés definiált, amely természetes módon értelmezett.

A decimal adattípusra alkalmazható korlátozó adattípus-tulajdonságok:

enumeration
fractionDigits
maxExclusive
maxInclusive
minExclusive
minInclusive
pattern
totalDigits
whiteSpace

double

64-bites lebegőpontos számok kezeléséhez biztosítja a szabvány a double adattípust.

Az értéktér formálisan az alakban kifejezhető számok halmaza, ahol és egész számok, amelyekre és . Speciálisan az értéktér részét képezi továbbá a következő három speciális érték: pozitív végtelen, negatív végtelen, NaN.

A lexikális tér elemei olyan karakterláncok, amelyek a mantisszát tartalmazzák, utána pedig opcionálisan az E vagy e karaktert követően a karakterisztikát. A mantisszát egy decimal, a karakterisztikát pedig egy integer típusú literál ábrázolja. A három speciális értéket az INF, -INF és NaN karakterláncok ábrázolják.

Érvényes literálok például: 42, -1E8, 3.141593, -0, 2.220446e-16

A kanonikus lexikális reprezentáció az alábbi módon definiált:

  • A karakterisztika jelzéséhez az E karakter használata kötelező.

  • A karakterisztika elején tilos vezező nullák és a + előjel karakter megadása.

  • E0 módon kötelező jelezni, ha a karakterisztika értéke 0.

  • A mantisszában tilos a + előjel karakter használata, viszont kötelező a decimális pont megadása. Tilos vezető és a decimális pontot követő szám végi nullák használata. A decimális pont karakter bal oldalán legalább egy nem nulla decimális számjegy karakter kötelező, a jobb oldalán legalább egy tetszőleges decimális számjegy. A decimális pont jobb oldalán speciálisan megengedett egyetlen 0 számjegy.

A fentiek alapján például a 0 számot a 0.0E0 literál ábrázolja a kanonikus lexikális reprezentációban.

Az értéktéren egy szigorú részbenrendezés definiált. A rendezés természetes módon értelmezhető, a NaN érték kezelése történik speciálisan. Összehasonlításban a NaN érték egyenlő önmagával, azonban nem összehasonlítható az értéktér egyetlen más elemével sem. A pozitív végtelen nagyobb minden NaN-tól és önmagától különböző értéknél, a negatív végtelen pedig kisebb minden NaN-tól és önmagától különböző értéknél.

A double adattípusra alkalmazható korlátozó adattípus-tulajdonságok:

enumeration
maxExclusive
maxInclusive
minExclusive
minInclusive
pattern
whiteSpace

duration

Időtartamok kezeléséhez biztosítja a szabvány a duration adattípust.

Az értéktér olyan hatdimenziós vektorok halmaza, ahol a komponensek az év, hónap, nap, óra, perc és másodperc komponensek értéket szolgáltatják.

A lexikális tér elemei PuYvMwDTxHyMzS formájú karakterláncok, ahol u, v, w, x, y és z az év, hónap, nap, óra, perc és másodperc komponensek értékei, amelyek közül az első öt tetszőleges előjel nélküli egész, az utolsó pedig egy előjel nélküli decimális szám. Ha a másodperc értéket szolgáltató decimális szám tartalmaz decimális pontot, akkor annak jobb oldalán legalább egy számjegy karakter kötelező. Negatív időtartamok jelzéséhez a literál elején megjelenhet a - előjel karakter.

A literálból el lehet hagyni azokat a komponenseket és jelölőiket, amelyek értéke 0, azonban legalább egy komponens és jelölője kötelező. A T jelölő kizárólag akkor hagyható el, ha az óra, perc és másodperc komponensek értéke 0.

Érvényes literálok például:

P1Y2DT5H30M (1 év, 2 nap, 5 óra és 30 perc)
P120Y6M (120 év és 6 hónap)
-PT65M80S (65 perc és 80 másodperc, negatív)
PT9.58S (9.58 másodperc)

Az értéktéren egy szigorú részbenrendezés értelmezett, mivel nem egyértelmű sem egy év, sem egy hónap napjainak száma.

[Figyelem]Figyelem

Például a P28D, P29D, P30D és P31D literálok által ábrázolt értékek egyike sem összehasonlítható a P1M literál által ábrázolt értékkel, azonban a P27D literálnak megfelelő érték a rendezésben megelőzi a P1M literálnak megfelelő értéket, utóbbi pedig a P32D literálnak megfelelő értéket.

A duration adattípusra alkalmazható korlátozó adattípus-tulajdonságok:

enumeration
maxExclusive
maxInclusive
minExclusive
minInclusive
pattern
whiteSpace

float

32-bites lebegőpontos számok kezeléséhez biztosítja a szabvány a float adattípust, amely mindössze az értéktér tekintetében különbözik a double adattípustól.

Az értéktér formálisan az olyan alakban kifejezhető számok halmaza, ahol és egész számok, amelyekre és . Speciálisan az értéktér részét képezi továbbá a következő három speciális érték: pozitív végtelen, negatív végtelen, NaN.

A lexikális tér, a kanonikus lexikális reprezentáció és az értéktéren értelmezett rendezés ugyanaz, mint a double adattípusnál.

A float adattípusra alkalmazható korlátozó adattípus-tulajdonságok:

enumeration
maxExclusive
maxInclusive
minExclusive
minInclusive
pattern
whiteSpace

gDay

A Gergely-naptár hónaponta ismétlődő napjait reprezentáló adattípus. Az értéktér elemei a Gergely-naptári hónapok napjai, amelyekhez hónap nem meghatározott. A lexikális tér elemei ---NN alakú literálok – NN a napot reprezentáló két decimális számjegy karakter –, amelyeket opcionálisan követhet időzóna jelző. Például ---05 a hónap ötödik napját jelölő literál.

Az értéktéren egy szigorú részbenrendezés definiált, amelyben az időzónás és időzóna nélküli értékek közül bizonyosak nem összehasonlíthatóak.

A gDay adattípusra alkalmazható korlátozó adattípus-tulajdonságok:

enumeration
maxExclusive
maxInclusive
minExclusive
minInclusive
pattern
whiteSpace

gMonth

A Gergely-naptár 12 hónapját reprezentáló adattípus. Az értékteret a Gergely-naptár hónapjai alkotják. A lexikális tér elemei --HH alakú literálok – HH a hónapot reprezentáló két decimális számjegy karakter –, amelyeket opcionálisan követhet időzóna jelző. Például a --03 literál a március hónapot jelöli.

Az értéktéren egy szigorú részbenrendezés definiált, amelyben az időzónás és időzóna nélküli értékek közül bizonyosak nem összehasonlíthatóak.

A gMonth adattípusra alkalmazható korlátozó adattípus-tulajdonságok:

enumeration
maxExclusive
maxInclusive
minExclusive
minInclusive
pattern
whiteSpace

gMonthDay

A Gergely-naptár évente ismétlődő dátumait reprezentáló adattípus, amely alkalmas például évfordulók napjának ábrázolásához. Az értéktér elemei a Gergely-naptár évente ismétlődő dátumai. A lexikális tér elemei --HH-NN alakú literálok – HH a hónapot, NN a napot reprezentáló két decimális számjegy karakter –, amelyeket opcionálisan követhet időzóna jelző.

Például a --05-25 literál május 25. napját jelöli, amely az úgynevezett Törülközőnap[5].

Az értéktéren egy szigorú részbenrendezés definiált, amelyben az időzónás és időzóna nélküli értékek közül bizonyosak nem összehasonlíthatóak.

A gMonthDay adattípusra alkalmazható korlátozó adattípus-tulajdonságok:

enumeration
maxExclusive
maxInclusive
minExclusive
minInclusive
pattern
whiteSpace

gYear

A Gergely-naptár éveit reprezentáló adattípus. Az értéktér elemei a Gergely-naptár évei. A lexikális tér elemei olyan évre csonkolt dateTime literálok, amelyeket opcionálisan követhet időzóna jelző.

Két érték összehasonlítása a kezdetük pillanatának összehasonlításával történik. Az értéktéren így egy szigorú részbenrendezés definiált, amelyben az időzónás és időzóna nélküli értékek közül bizonyosak nem összehasonlíthatóak.

Érvényes literálok például: -0753 (Róma alapításának éve a hagyomány szerint), 0476 (a Nyugatrómai Birodalom bukásának éve), 1984, 802701 (ebbe az évbe kerül Wells időutazója Az időgép című sci-fi klasszikusában).

A gYear adattípusra alkalmazható korlátozó adattípus-tulajdonságok:

enumeration
maxExclusive
maxInclusive
minExclusive
minInclusive
pattern
whiteSpace

gYearMonth

A Gergely-naptár éveinek hónapjait reprezentáló adattípus. Az értéktér elemei a Gergely-naptár éveinek hónapjai. A lexikális tér elemei olyan ÉÉÉÉ-HH alakú évre és hónapra csonkolt dateTime literálok, amelyeket opcionálisan követhet időzóna jelző.

Például az 1848-03 literál jelöli 1848 márciusát.

Két érték összehasonlítása a kezdetük pillanatának összehasonlításával történik. Az értéktéren így egy szigorú részbenrendezés definiált, amelyben az időzónás és időzóna nélküli értékek közül bizonyosak nem összehasonlíthatóak.

A gYearMonth adattípusra alkalmazható korlátozó adattípus-tulajdonságok:

enumeration
maxExclusive
maxInclusive
minExclusive
minInclusive
pattern
whiteSpace

hexBinary

Hexadecimálisan kódolt bináris adatok kezelésére szolgáló adattípus. A hexadecimális kódolás bináris oktettsorozatokat kódol hexadecimális számjegyekből álló karaktersorozatokkal. A kódolásban minden oktettet a két megfelelő hexadecimális számjegy karakter (00, …, FF) ábrázol.

Az értéktér a (kódolandó) véges oktettsorozatok, a lexikális tér pedig az ezeket kódoló karaktersorozatok halmaza. A kanonikus lexikális reprezentációban hexadecimális számjegyként csak kisbetű karakterek haszálata megengedett.

A hexBinary adattípusra alkalmazható korlátozó adattípus-tulajdonságok:

enumeration
length
maxLength
minLength
pattern
whiteSpace

NOTATION

Az [XML 1.0] specifikáció NOTATION tulajdonságtípusával kompatibilis adattípus.

[Fontos]Fontos

A NOTATION adattípus közvetlenül nem használható sémákban, csak belőle az enumeration korlátozó adattípus-tulajdonság értékének megadásával származtatott adattípus.

A NOTATION adattípusra alkalmazható korlátozó adattípus-tulajdonságok:

enumeration
length
maxLength
minLength
pattern
whiteSpace

QName

Az XML névterek kapcsán használt és az [XML Names] specifikációban definiált minősített nevek kezelésére szolgáló adattípus. Az értéktér elemei kifejtett nevek, a lexikális tér elemei pedig minősített nevek. A minősített nevek kifejtett neveknek történő megfeleltetése az egyes előfordulásoknál érvényben lévő névtér-deklarációk alapján történik.

Egy érvényes literál például xml:lang, amely a http://www.w3.org/XML/1998/namespace névtér-névből és lang lokális névből álló kifejtett nevet jelöli.

A QName adattípusra alkalmazható korlátozó adattípus-tulajdonságok:

enumeration
length
maxLength
minLength
pattern
whiteSpace

string

Karakterláncokat ábrázoló adattípus. Az értéktér és a lexikális tér az XML dokumentumokban megengedett karakterekből álló véges hosszúságú karaktersorozatok halmaza.

Megjegyezzük, hogy az értéktéren nem értelmezett rendezés.

A string adattípusra alkalmazható korlátozó adattípus-tulajdonságok:

enumeration
length
maxLength
minLength
pattern
whiteSpace

time

Naponta ismétlődő időpillanatokat ábrázoló adattípus.

Az értéktér a 24 órás időértékek halmaza.

A lexikális tér elemei az idő komponensre csonkolt dateTime literálok, azaz hh:mm:ss[.sss] formájúak, amelyet opcionálisan időzóna jelző követhet.

Érvényes literálok például: 12:15:00 (nincs időzóna) , 23:05:30Z (egyezményes koordinált világidő) , 00:45:00+01:00 (közép-európai idő)

A kanonikus lexikális reprezentációban időzóna jelzőként csak az egyezményes koordinált világidőt jelentő Z megengedett, továbbá 00:00:00 az éjfél kanonikus lexikális reprezentációja.

A time adattípusra alkalmazható korlátozó adattípus-tulajdonságok:

enumeration
maxExclusive
maxInclusive
minExclusive
minInclusive
pattern
whiteSpace

Beépített származtatott adattípusok

A decimal típusból származtatott beépített adattípusok

A decimal típusból (megszorítással) származtatott beépített adattípusok mind egész adattípusok, amelyek az értéktér tartományában különböznek. Közülük előjel nélküliek azok a típusok, amelyek neve az unsigned előtaggal kezdődik, a többi pedig előjeles.

A lexikális teret mindegyik adattípusnál decimális számjegy karakterekből álló literálok alkotják, amelyekben az előjeles típusok esetén megengedett előjel karakter használata is, az előjel nélküli típusok esetén azonban tilos.

A kanonikus lexikális reprezentáció is megegyezik az ide tartozó típusoknál: tilos vezető nullák, előjeles típusok esetén pedig a + előjel karakter használata is.

Mivel a decimal típus értékterén egy szigorú teljes rendezés definiált, a belőle származtatott adattípusok esetén is ennek megfelelő szigorú teljes rendezés értelmezett.

A decimal típusból származtatott adattípusokra alkalmazható korlátozó adattípus-tulajdonságok:

enumeration
fractionDigits
maxExclusive
maxInclusive
minExclusive
minInclusive
pattern
totalDigits
whiteSpace

A.1. ábra - A decimal típusból (megszorítással) származtatott adattípusok

A decimal típusból (megszorítással) származtatott adattípusok

A.1. táblázat - A decimal típusból (megszorítással) származtatott adattípusok értéktere

NévTartomány
byte
int
integer
long
negativeInteger
nonNegativeInteger
nonPositiveInteger
positiveInteger
short
unsignedByte
unsignedInt
unsignedLong
unsignedShort

A string típusból származtatott beépített adattípusok

A string adattípusból származtatott beépített adattípusok többsége atomi adattípus, de van köztük néhány lista adattípus.

Minden a string adattípusból származtatott beépített adattípusra a következő korlátozó adattípus-tulajdonságok alkalmazhatóak:

enumeration
length
maxLength
minLength
pattern
whiteSpace

A.2. ábra - A string adattípusból származtatott beépített adattípusok. Az éleknél a folytonos vonal megszorítással történő származtatást, a szaggatott vonal pedig lista képzésével történő származtatást jelent.

A string adattípusból származtatott beépített adattípusok. Az éleknél a folytonos vonal megszorítással történő származtatást, a szaggatott vonal pedig lista képzésével történő származtatást jelent.

ENTITY

Az [XML 1.0] ENTITY tulajdonságtípusával kompatibilis, az NCName adattípusból megszorítással származtatott adattípus.

Kompatibilitási okokból használata csak tulajdonságokhoz ajánlott.

ENTITIES

Az [XML 1.0] ENTITIES tulajdonságtípusával kompatibilis, az ENTITY adattípusból származtatott lista adattípus.

Kompatibilitási okokból használata csak tulajdonságokhoz ajánlott.

ID

Az [XML 1.0] ID tulajdonságtípusával kompatibilis, az NCName adattípusból megszorítással származtatott adattípus. Az értéktér és a lexikális tér azon karakterláncok halmaza, amelyek érvényes XML nevek és nem tartalmaznak : karaktert.

Kompatibilitási okokból használata csak tulajdonságokhoz ajánlott.

IDREF

Az [XML 1.0] IDREF tulajdonságtípusával kompatibilis, az NCName adattípusból megszorítással származtatott adattípus. Az értéktér és a lexikális tér azon karakterláncok halmaza, amelyek érvényes XML nevek és nem tartalmaznak : karaktert.

Kompatibilitási okokból használata csak tulajdonságokhoz ajánlott.

IDREFS

Az [XML 1.0] IDREFS tulajdonságtípusával kompatibilis, az IDREF adattípusból származtatott lista adattípus. Az értéktér elemei IDREF értékekből álló véges és nemüres sorozatok. A lexikális tér azon karakterláncok halmaza, amelyek szóköz karakterekkel elválasztott IDREF literálokat tartalmaznak.

Kompatibilitási okokból használata csak tulajdonságokhoz ajánlott.

language

A token adattípusból megszorítással származtatott, természetes nyelveket azonosító címkéket ábrázoló adattípus. Az értéktér és a lexikális tér az [RFC 3066] specifikációban meghatározott formájú, természetes nyelveket azonosító címkék halmaza.

A természetes nyelveket azonosító címkék mindegyike tartalmaz egy elsődleges alcímkét, amelyet tetszőleges számú további alcímke követhet. Több alcímkéke esetén a - karaktert kell elválasztóként használni. Minden címke legalább 1 és legfeljebb 8 karaktert tartalmaz. Az elsődleges alcímkében az angol ábécé kis- és nagybetű karakterei megengedettek, a további alcímkékben pedig az angol ábécé kis- és nagybetű karakterei valamint a decimális számjegy karakterek.

[Megjegyzés]Megjegyzés

Elsődleges alcímkeként két vagy három karakterből álló szabványos kódokat használunk. A kétbetűs kódokat az ISO 639-1:2002 szabvány definiálja, a hárombetűs kódokat pedig az ISO 639-2:1998, ISO 639-3:2007 és ISO 639-5:2008 szabványok tartalmazzák.

Érvényes literálok például: en (angol), en-GB (britt angol), en-US (amerikai angol)

Name

XML neveket reprezentáló, a token adattípusból megszorítással származtatott adattípus. Az értéktér és a lexikális tér azon karakterláncok halmaza, amelyek érvényes XML nevek.

Érvényes literálok például: title, xml:lang, sw:midichlorianCount

NCName

Kettőspont karaktert nem tartalmazó XML neveket reprezentáló, a Name adattípusból megszorítással származtatott adattípus. Az értéktér és a lexikális tér azon karakterláncok halmaza, amelyek érvényes XML nevek és nem tartalmaznak : karaktert. (Az [XML Names] specifikáció használja az ilyen nevekre az NCName kifejezést.)

Érvényes literálok például: title, xml, lang, sw, midichlorianCount

NMTOKEN

Az [XML 1.0] NMTOKEN tulajdonságtípusával kompatibilis, a token adattípusból megszorítással származtatott adattípus. Az értéktér és a lexikális tér azon karakterláncok halmaza, amelyek érvényes névtokenek.

Kompatibilitási okokból használata csak tulajdonságokhoz ajánlott.

Érvényes literálok például: fontos, 10th_floor, 1975-06-22

NMTOKENS

Az [XML 1.0] NMTOKEN tulajdonságtípusával kompatibilis, a NMTOKEN adattípusból származtatott lista adattípus. Az értéktér elemei NMTOKEN értékekből álló véges és nemüres sorozatok. A lexikális tér azon karakterláncok halmaza, amelyek szóköz karakterekkel elválasztott NMTOKEN literálokat tartalmaznak.

Kompatibilitási okokból használata csak tulajdonságokhoz ajánlott.

Érvényes literálok például: indul a görög aludni, 10th floor, 118 154 387 670

normalizedString

Whitespace-normalizált karakterláncokat reprezentáló, a string típusból származtatott adattípus. Az értéktér és a lexikális tér elemei a TAB (U+0009), LF (U+000A) és CR (U+000D) karaktereket nem tartalmazó karakterláncok.

token

Tokenizált karakterláncokat reprezentáló, a normalizedString típusból származtatott adattípus. Az értéktér és a lexikális tér elemei a TAB (U+0009), LF (U+000A) és CR (U+000D) karaktereket nem tartalmazó karakterláncok, amelyek elején és végén sincs szóköz karakter, valamint nem tartalmaznak egynél több közvetlenül egymást követő szóköz karaktert sem.



[5] A Törülközőnap Douglas Adams író, a Galaxis útikalauz stopposoknak című könyv szerzője előtti tisztelgés.

B. függelék - Korlátozó adattípus-tulajdonságok

Ez a függelék az adattípusok megszorítással történő származtatásához rendelkezésre álló korlátozó adattípus-tulajdonságokat mutatja be. Az enumeration és pattern elemek kivételével az adattípus tulajdonságokat ábrázoló XML elemek mindegyike legfeljebb egyszer fordulhat elő egy megszorítást kifejező restriction elemben. Az [XML Schema: Datatypes] specifikáció kínos pontossággal szabályozza az adattípus-tulajdonságok származtatásban való használatát, a pontos részletektől megkíméljük az olvasót. Az aranyszabály az, hogy az adattípus-tulajdonságokat nem alkalmazhatjuk ellentmondásosan, az alkalmazás során pedig csak az alaptípus értékterének szűkítése és változatlanul hagyása megengedett.

enumeration

Minden adattípusra alkalmazható az enumeration korlátozó adattípus-tulajdonság, amely révén felsorolással adott értékek egy halmazára szűkíthető az értéktér.

Minden restriction elemben tetszőleges számú enumeration elem fordulhat elő, amelyek mindegyikének értékeként az alaptípus értékterének egy elemét kötelező megadni. Az enumeration elemek az értékeikként adott literáloknak megfelelő értékek halmazára szűkítik az értékteret.

Az enumeration adattípus-tulajdonsággal származtatott adattípusokat felsorolásoknak is nevezik.

B.1. példa - Az enumeration korlátozó adattípus-tulajdonság alkalmazása

Az alábbi módon definiált, a beépített token adattípusból származtatott adattípus értékterét a private, protected és public karakterláncok alkotják:

<xs:simpleType name="modifier">
    <xs:restriction base="xs:token">
        <xs:enumeration value="private"/>
        <xs:enumeration value="protected"/>
        <xs:enumeration value="public"/>
    </xs:restriction>
</xs:simpleType>


B.2. példa - Az enumeration korlátozó adattípus-tulajdonság alkalmazása

Az alábbi módon definiált, a beépített double adattípusból származtatott adattípus értékterét a NaN, -INF és INF értékek alkotják:

<xs:simpleType>
    <xs:restriction base="xs:double">
        <xs:enumeration value="NaN"/>
        <xs:enumeration value="-INF"/>
        <xs:enumeration value="INF"/>
    </xs:restriction>
</xs:simpleType>


fractionDigits

A decimal adattípusra és a belőle megszorítással származtatott adattípusokra alkalmazható korlátozó adattípus-tulajdonság, amelynek értéke egy nemnegatív egész. Típusdefinícióban való előfordulása az értékteret az olyan alakban kifejezhető számok halmazára korlátozza, ahol egész szám, pedig olyan egész szám, amelyre . Ez szemléletesen azt jelenti, hogy értéke a decimális pont karakter jobb oldalán megadható értékes számjegyek maximális számát határozza meg. (Megengedi azonban a decimális pont karaktert követő nulla számjegyek használatát a szám végén.)

Értéke nem lehet nagyobb a totalDigits korlátozó adattípus-tulajdonság értékénél.

B.3. példa - A fractionDigits korlátozó adattípus-tulajdonság alkalmazása

<xs:simpleType>
    <xs:restriction base="xs:decimal">
        <xs:fractionDigits value="2"/>
    </xs:restriction>
</xs:simpleType>

length, minLength, maxLength

Az anyURI, base64Binary, hexBinary és string adattípusokra, a belőlük megszorítással származtatott adattípusokra valamint a lista adattípusokra alkalmazható korlátozó adattípus-tulajdonságok, amelyek értéke egy nemnegatív egész.

Mindhárom adattípus-tulajdonság az értéktér elemeinek hosszát korlátozza, ahol a hossz jelentése adattípus-függő:

  • Az anyURI és string adattípusok valamint a belőlük megszorítással származtatott adattípusok esetén a karakterek számát jelenti.

  • A base64Binary és hexBinary adattípusok valamint a belőlük megszorítással származtatott adattípusok esetén az oktettek számát jelenti.

  • Lista adattípusok esetén az elemek számát jelent.

Megjegyezzük, hogy a specifikáció megengedi mindhárom adattípus-tulajdonság alkalmazását a NOTATION és QName adattípusokra valamint a belőlük megszorítással származtatott adattípusokra, azonban ezek esetében a tulajdonságoknak nincs hatása.

length

A length adattípus-tulajdonság az értéktér elemeinek kötelező hosszát határozza meg.

A length elem nem fordulhat elő a maxLength és minLength elemekkel együtt ugyanabban a restriction elemben.

B.4. példa - A length korlátozó adattípus-tulajdonság alkalmazása

Az alábbi módon definiált, a beépített string adattípusból származtatott adattípus értékterét a pontosan 10 karaktert tartalmazó karakterláncok alkotják:

<xs:simpleType>
    <xs:restriction base="xs:string">
        <xs:length value="10"/>
    </xs:restriction>
</xs:simpleType>

B.5. példa - A length korlátozó adattípus-tulajdonság alkalmazása

Az alábbi módon definiált lista adattípus értékterét float típusú értékekből képzett háromelemű listák alkotják:

<xs:simpleType name="coordinates">
    <xs:restriction>
        <xs:simpleType>
            <xs:list itemType="xs:float"/>
        </xs:simpleType>
        <xs:length value="3"/>
    </xs:restriction>
</xs:simpleType>


maxLength

A maxLength adattípus-tulajdonság az értéktér elemeinek kötelező maximális hosszát határozza meg.

B.6. példa - A maxLength korlátozó adattípus-tulajdonság alkalmazása

Az alábbi módon definiált, a beépített string adattípusból származtatott adattípus értékterét a legfeljebb 128 karaktert tartalmazó karakterláncok alkotják:

<xs:simpleType>
    <xs:restriction base="xs:string">
        <xs:maxLength value="128"/>
    </xs:restriction>
</xs:simpleType>

minLength

A minLength adattípus-tulajdonság az értéktér elemeinek kötelező minimális hosszát határozza meg.

Értéke nem lehet nagyobb a maxLength korlátozó adattípus-tulajdonság értékénél.

B.7. példa - A minLength korlátozó adattípus-tulajdonság alkalmazása

Az alábbi módon definiált, a beépített string adattípusból származtatott adattípus értékterét a legalább 3 karaktert tartalmazó karakterláncok alkotják:

<xs:simpleType>
    <xs:restriction base="xs:string">
        <xs:minLength value="3"/>
    </xs:restriction>
</xs:simpleType>

minExclusive, minInclusive, maxInclusive, maxExclusive

Olyan adattípusokra alkalmazhatóak a minExclusive, minInclusive, maxInclusive és maxExclusive adattípus-tulajdonságok, amelyek értékterén rendezés értelmezett.

Mind a négy adattípus-tulajdonság értékeként az alaptípus értékterének egy elemét kötelező megadni. Az adattípus-tulajdonságok az értéküktől szigorúan nagyobb, nagyobb vagy egyenlő, kisebb vagy egyenlő illetve szigorúan kisebb értékek halmazára szűkítik az alaptípus értékterét. Következményként kizárásra kerülnek az alaptípus értékterének az adott értékkel nem összehasonlítható elemei.

maxInclusive

A maxInclusive adattípus-tulajdonság az értékénél kisebb vagy egyenlő értékek halmazára szűkíti az alaptípus értékterét.

Nem megengedett a minInclusive adattípus-tulajdonsághoz a maxInclusive adattípus-tulajdonság értékénél nagyobb érték.

maxExclusive

A maxExclusive adattípus-tulajdonság az értékénél szigorúan kisebb értékek halmazára szűkíti az alaptípus értékterét.

Nem fordulhat elő a maxInclusive és a maxExclusive elem ugyanabban a restriction elemben. Nem megengedett a minExclusive adattípus-tulajdonsághoz a maxExclusive adattípus-tulajdonság értékénél nagyobb érték.

B.8. példa - A maxExclusive korlátozó adattípus-tulajdonság alkalmazása

Az alábbi módon definiált, a beépített gYear adattípusból származtatott adattípus értékterét az időszámításunk előtt naptári évek alkotják:

<xs:simpleType name="bcYear">
    <xs:restriction base="xs:gYear">
        <xs:maxExclusive value="0001"/>
    </xs:restriction>
</xs:simpleType>


minExclusive

A minExclusive adattípus-tulajdonság az értékénél szigorúan nagyobb értékek halmazára szűkíti az alaptípus értékterét.

Nem fordulhat elő a minInclusive és a minExclusive elem ugyanabban a restriction elemben. Nem megengedett a minExclusive adattípus-tulajdonsághoz a maxInclusive adattípus-tulajdonság értékénél nagyobb vagy egyenlő érték.

B.9. példa - A minExclusive korlátozó adattípus-tulajdonság alkalmazása

Az alábbi módon definiált, a beépített double adattípusból származtatott adattípus értékterét a pozitív double típusú számok alkotják:

<xs:simpleType name="positiveDouble">
    <xs:restriction base="xs:double">
        <xs:minExclusive value="0"/>
    </xs:restriction>
</xs:simpleType>


minInclusive

A minInclusive adattípus-tulajdonság az értékénél nagyobb vagy egyenlő értékek halmazára szűkíti az alaptípus értékterét.

Nem megengedett a minInclusive adattípus-tulajdonsághoz a maxExclusive adattípus-tulajdonság értékénél nagyobb vagy egyenlő érték.

B.10. példa - A minInclusive korlátozó adattípus-tulajdonság alkalmazása

Az alábbi módon definiált, a beépített integer adattípusból származtatott adattípus értékterét a 18-nál nagyobb vagy egyenlő egész számok alkotják:

<xs:simpleType name="adultAge">
    <xs:restriction base="xs:integer">
        <xs:minInclusive value="18"/>
    </xs:restriction>
</xs:simpleType>


pattern

Minden adattípusra alkalmazható a pattern korlátozó adattípus-tulajdonság, amely révén adott reguláris kifejezésekre illeszkedő literálok halmazára szűkíthető a lexikális tér. (Amely az értéktér megfelelő szűkítését is maga után vonja.)

Minden restriction elemben tetszőleges számú pattern elem fordulhat elő, amelyek mindegyikének értékeként egy reguláris kifejezést kell megadni. Az ugyanabban a restriction elemben gyermekként előforduló pattern elemek az alaptípus lexikális terét azon literálok halmazára szűkítik, amelyek illeszkednek valamelyik reguláris kifejezésre.

B.11. példa - A pattern korlátozó adattípus-tulajdonság alkalmazása

Az alábbi módon definiált, a beépített anyURI adattípusból származtatott adattípus lexikális terének elemei a mailto: kezdőszeletű URI karakterláncok:

<xs:simpleType name="mailtoURI">
    <xs:restriction base="xs:anyURI">
        <xs:pattern value="mailto:.*"/>
    </xs:restriction>
</xs:simpleType>


B.12. példa - A pattern korlátozó adattípus-tulajdonság alkalmazása

Az alábbi módon definiált, a beépített decimal adattípusból származtatott adattípus értékterének elemei 10 egész kitevőjű hatványai:

<xs:simpleType name="powerOfTen">
    <xs:restriction base="xs:decimal">
        <xs:pattern value="1(0)*"/>
        <xs:pattern value="0.(0)*1"/>
    </xs:restriction>
</xs:simpleType>

Érvényes literálok például a következő karakterláncok: 0.01, 0.1, 1, 10, 100

Megjegyezzük, hogy a fenti típusdefinícióval ekvivalens az alábbi:

<xs:simpleType name="powerOfTen">
    <xs:restriction base="xs:decimal">
        <xs:pattern value="(1(0)*)|(0.(0)*1)"/>
    </xs:restriction>
</xs:simpleType>


totalDigits

A decimal adattípusra és a belőle megszorítással származtatott adattípusokra alkalmazható korlátozó adattípus-tulajdonság, amelynek értéke egy nemnegatív egész. Típusdefinícióban való előfordulása az értékteret az olyan alakban kifejezhető számok halmazára korlátozza, ahol és egész számok, amelyekre és . Ez szemléletesen azt jelenti, hogy értéke a számot alkotó értékes számjegyek maximális számát határozza meg. (Megengedi azonban a szám elején és a decimális pont karakter után a szám végén nulla számjegyek használatát.)

B.13. példa - A totalDigits korlátozó adattípus-tulajdonság alkalmazása

Az alábbi módon definiált, a beépített decimal adattípusból származtatott adattípus értékterének elemei a legfeljebb öt értékes számjegyet tartalmazó számok:

<xs:simpleType>
    <xs:restriction base="xs:decimal">
        <xs:totalDigits value="5"/>
    </xs:restriction>
</xs:simpleType>

Érvényes literálok például a következő karakterláncok: 18.42, 3.1415, 012345, 345.120


whiteSpace

Atomi és lista adattípusokra alkalmazható korlátozó adattípus-tulajdonság, amellyel a whitespace normalizálás szabályozható. Lehetséges értékei preserve, replace és collapse.

A string adattípus és a belőle megszorítással származtatott adattípusok kivételével minden beépített atomi adattípus esetén collapse a whiteSpace adattípus-alaptulajdonság értéke, amely nem változtatható meg.

A string adattípus esetén preserve a whiteSpace adattípus-alaptulajdonság értéke, belőle megszorítással történő származtatás során azonban mindhárom lehetséges érték használható.

Minden lista adattípus esetén collapse a whiteSpace adattípus-alaptulajdonság értéke, amely nem változtatható meg.

Megszorítással történő származtatás során nem megengedett az adattípus-tulajdonság értékének alábbi módosítása:

  • Az alaptípustól örökölt collapse érték felülírása preserve vagy replace értékkel.

  • Az alaptípustól örökölt replace érték felülírása preserve értékkel.

C. függelék - Dokumentumok az Esettanulmány című fejezethez

XML séma

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:attribute name="cond" type="xs:string"/>
    <xs:attribute name="expr" type="xs:string"/>

    <xs:complexType name="emptyStatement"/>

    <xs:complexType name="emptyStatementWithExpr">
        <xs:attribute ref="expr" use="required"/>
    </xs:complexType>

    <xs:complexType name="emptyStatementWithCond">
        <xs:attribute ref="cond" use="required"/>
    </xs:complexType>

    <xs:element name="assign">
        <xs:complexType>
            <xs:attribute name="var" type="xs:NCName" use="required"/>
            <xs:attribute ref="expr" use="required"/>
        </xs:complexType>
    </xs:element>

    <xs:element name="exit" type="emptyStatement"/>

    <xs:element name="printOrPrintln" abstract="true">
        <xs:complexType mixed="true">
            <xs:sequence>
                <xs:element name="value" type="emptyStatementWithExpr" minOccurs="0" maxOccurs="unbounded"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="print" substitutionGroup="printOrPrintln"/>

    <xs:element name="println" substitutionGroup="printOrPrintln"/>

    <xs:group name="topLevelStatement">
        <xs:choice>
            <xs:element ref="assign"/>
            <xs:element ref="exit"/>
            <xs:element name="if" type="topLevelIf"/>
            <xs:element ref="printOrPrintln"/>
            <xs:element ref="while"/>
        </xs:choice>
    </xs:group>

    <xs:group name="innerStatement">
        <xs:choice>
            <xs:element ref="assign"/>
            <xs:element name="break" type="emptyStatement"/>
            <xs:element name="continue" type="emptyStatement"/>
            <xs:element ref="exit"/>
            <xs:element name="if" type="innerIf"/>
            <xs:element ref="printOrPrintln"/>
            <xs:element ref="while"/>
        </xs:choice>
    </xs:group>

    <xs:complexType name="innerStatementList">
        <xs:group ref="innerStatement" minOccurs="0" maxOccurs="unbounded"/>
    </xs:complexType>

    <xs:complexType name="topLevelStatementList">
        <xs:complexContent>
            <xs:restriction base="innerStatementList">
                <xs:group ref="topLevelStatement" minOccurs="0" maxOccurs="unbounded"/>
            </xs:restriction>
        </xs:complexContent>
    </xs:complexType>

    <xs:element name="program" type="topLevelStatementList"/>

    <xs:element name="while">
        <xs:complexType>
            <xs:complexContent>
                <xs:extension base="innerStatementList">
                    <xs:attribute ref="cond" use="required"/>
                </xs:extension>
            </xs:complexContent>
        </xs:complexType>
    </xs:element>

    <xs:element name="if" type="topLevelIf"/>

    <xs:complexType name="innerIf">
        <xs:sequence>
            <xs:choice minOccurs="0" maxOccurs="unbounded">
                <xs:group ref="innerStatement"/>
                <xs:element name="elseif" type="emptyStatementWithCond"/>
            </xs:choice>
            <xs:sequence minOccurs="0" maxOccurs="1">
                <xs:element name="else" type="emptyStatement"/>                
                <xs:group ref="innerStatement" minOccurs="0" maxOccurs="unbounded"/>
            </xs:sequence>
        </xs:sequence>
        <xs:attribute ref="cond" use="required"/>
    </xs:complexType>

    <xs:complexType name="topLevelIf">
        <xs:complexContent>
            <xs:restriction base="innerIf">
                <xs:sequence>
                    <xs:choice minOccurs="0" maxOccurs="unbounded">
                        <xs:group ref="topLevelStatement"/>
                        <xs:element name="elseif" type="emptyStatementWithCond"/>
                    </xs:choice>
                    <xs:sequence minOccurs="0" maxOccurs="1">
                        <xs:element name="else" type="emptyStatement"/>                
                        <xs:group ref="topLevelStatement" minOccurs="0" maxOccurs="unbounded"/>
                    </xs:sequence>
                </xs:sequence>
            </xs:restriction>
        </xs:complexContent>
    </xs:complexType>

</xs:schema>

XSLT stíluslap

Az alábbi XSLT stíluslap egy ekvivalens, ANSI C programmá alakít minden, a bemutatott sémának megfelelő XML dokumentumot.

<?xml version="1.0"?>
<!DOCTYPE xsl:stylesheet [
    <!ENTITY tabulator "&#9;">
    <!ENTITY newline "&#10;">
]>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:output method="text"/>

    <xsl:template match="program">
        <xsl:text>#include &lt;stdio.h&gt;&newline;</xsl:text>
        <xsl:text>#include &lt;stdlib.h&gt;&newline;</xsl:text>
        <xsl:call-template name="declarations"/>
        <xsl:text>int main(int argc, char **argv) {&newline;</xsl:text>
            <xsl:apply-templates select="*"/>
        <xsl:text>return 0;&newline;}&newline;</xsl:text>
    </xsl:template>

    <xsl:template match="assign">
        <xsl:value-of select="@var"/> <xsl:text> = </xsl:text> <xsl:value-of select="@expr"/> <xsl:text>;&newline;</xsl:text>
    </xsl:template>

    <xsl:template match="break">
        <xsl:text>break;&newline;</xsl:text>
    </xsl:template>

    <xsl:template match="continue">
        <xsl:text>continue;&newline;</xsl:text>
    </xsl:template>

    <xsl:template match="exit">
        <xsl:text>exit(0);&newline;</xsl:text>
    </xsl:template>

    <xsl:template match="if">
        <xsl:text>if (</xsl:text> <xsl:value-of select="@cond"/> <xsl:text>) {&newline;</xsl:text>
            <xsl:apply-templates select="*"/>
        <xsl:text>}&newline;</xsl:text>
    </xsl:template>

    <xsl:template match="elseif">
        <xsl:text>} else if (</xsl:text> <xsl:value-of select="@cond"/> <xsl:text>) {&newline;</xsl:text>
    </xsl:template>

    <xsl:template match="else">
        <xsl:text>} else {&newline;</xsl:text>
    </xsl:template>

    <xsl:template match="print|println">
        <xsl:text>printf("</xsl:text>
        <xsl:apply-templates select="child::node()" mode="format-string"/>
        <xsl:if test="name() = 'println'">
            <xsl:text>\n</xsl:text>
        </xsl:if>
        <xsl:text>"</xsl:text>
        <xsl:for-each select="value">
            <xsl:text>, </xsl:text>
            <xsl:value-of select="@expr"/>
        </xsl:for-each>
        <xsl:text>);&newline;</xsl:text>
    </xsl:template>

    <xsl:template match="while">
        <xsl:text>while (</xsl:text> <xsl:value-of select="@cond"/> <xsl:text>) {&newline;</xsl:text>
            <xsl:apply-templates select="*"/>
        <xsl:text>}</xsl:text>
    </xsl:template>

    <xsl:template name="declarations">
        <xsl:for-each select="//assign[not(preceding::assign/@var = @var)]/@var">
            <xsl:sort select="."/>
            <xsl:text>int </xsl:text> <xsl:value-of select="."/> <xsl:text>;&newline;</xsl:text>
        </xsl:for-each>
    </xsl:template>

    <xsl:template match="text()" mode="format-string">
        <xsl:call-template name="replace-all-occurrences">
            <xsl:with-param name="text">
                <xsl:call-template name="replace-all-occurrences">
                    <xsl:with-param name="text">
                        <xsl:call-template name="replace-all-occurrences">
                            <xsl:with-param name="text">
                                <xsl:call-template name="replace-all-occurrences">
                                    <xsl:with-param name="text" select="."/>
                                    <xsl:with-param name="search" select="'\'"/>
                                    <xsl:with-param name="replace" select="'\\'"/>
                                </xsl:call-template>
                            </xsl:with-param>
                            <xsl:with-param name="search">
                                <xsl:text>&newline;</xsl:text>
                            </xsl:with-param>
                            <xsl:with-param name="replace" select="'\n'"/>
                        </xsl:call-template>
                    </xsl:with-param>
                    <xsl:with-param name="search">
                        <xsl:text>&tabulator;</xsl:text>
                    </xsl:with-param>
                    <xsl:with-param name="replace" select="'\t'"/>
                </xsl:call-template>
            </xsl:with-param>
            <xsl:with-param name="search" select="'&quot;'"/>
            <xsl:with-param name="replace" select="'\&quot;'"/>
        </xsl:call-template>
    </xsl:template>

    <xsl:template match="value" mode="format-string">
        <xsl:text>%d</xsl:text>
    </xsl:template>

    <xsl:template name="replace-all-occurrences">
        <xsl:param name="text"/>
        <xsl:param name="search"/>
        <xsl:param name="replace"/>
        <xsl:choose>
            <xsl:when test="contains($text, $search)">
                <xsl:value-of select="concat(substring-before($text, $search), $replace)"/>
                <xsl:call-template name="replace-all-occurrences">
                    <xsl:with-param name="text" select="substring-after($text, $search)"/>
                    <xsl:with-param name="search" select="$search"/>
                    <xsl:with-param name="replace" select="$replace"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$text"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>

Mivel nem az XSLT a könyv témájának tárgya, a stíluslap működésének bemutatásától eltekintünk. Alább a transzformáció eredményét adjuk meg a korábbi példában szereplő programra.

C.1. példa - Az XSLT stíluslap által előállított ANSI C program

Az alábbi kimenetet állítja elő az XSLT stíluslap a korábbi példa programjára (legnagyobb közös osztó meghatározása euklideszi algoritmussal):

#include <stdio.h>
#include <stdlib.h>
int a;
int b;
int main(int argc, char **argv)
{
    a = 1234;
    b = 563;
    while (a != b) {
        if (a > b) {
            a = a - b;
        } else {
            b = b - a;
        }
    }
    printf("A legnagyobb közös osztó: %d\n", a);
    return 0;
}

Megjegyezzük, hogy az XSLT stíluslap nem esztétikus C forráskódot állít elő, a létrehozott kódban minden utasítás automatikusan egy új sor elejére kerül. Az utasítások egymásba ágyazottságát tükröző esztétikus kód előállítása reménytelen feladat, amelyre kár időt pazarolni. A transzformáció eredményét az indent programmal alakítottuk a K&R (azaz Kernighan és Ritchie-féle) kódolási stílusnak megfelelő esztétikus alakra.


D. függelék - Sémadokumentumok manipulálása

Ajánlott szoftverek

<oXygen/> XML Editor

A szerző nem csupán sémadokumentumok, hanem általában XML dokumentumok manipulálásához a SyncRO Soft Ltd. <oXygen/> XML Editor termékét ajánlja, amely egy rendkívül sokoldalú XML szerkesztő. Sajnos nem szabad és nyílt forrású szoftver, azonban a szerzőnek nincs tudomása hasonló képességekkel rendelkező, ugyanakkor szabadon elérhető alternatíva létezéséről.

Az <oXygen/> Java-ban készült platformfüggetlen szoftver, amely Windows, Linux, Mac OS X és más egyéb rendszerekben is futtatható, de rendelkezésre áll Eclipse bővítményként is. A program letölthető kipróbálásra, amely közben valamennyi funkciója működik, azonban csak harminc napig használható.

Számunkra legfontosabb jellemzője, hogy teljeskörű támogatást ad az XML Schema, RELAX NG és Schematron sémanyelvekhez, felhasználóbarát módon téve lehetővé sémadokumentumok kezelését.

XMLSpy

Az <oXygen/> egy hasonlóan nem szabad alternatívája az Altova XMLSpy terméke, amely Windows platformra készült, azonban megfelelő eszközökkel más operációs rendszerekben is futtatható. (Unix-szerű operációs rendszerekben a Wine, Mac OS X rendszerekben a Parallels Desktop for Mac szoftverrel.)

Az <oXygen/> használata sémadokumentumokhoz

Sémadokumentumok megnyitása

Az állományrendszerben lokálisan rendelkezésre álló sémadokumentumok megnyitása megszokott módon a FileOpen… ( Ctrl+O ) menüpont kiválasztásával történik.

Távoli dokumentumok megnyitásához a FileOpen URL… ( Ctrl+U ) menüpont áll rendelkezésre. A módosítás is támogatott az FTP, SFTP és WebDAV protokollokal történő elérés esetén.

Sémadokumentumok létrehozása

Dokumentumok létrehozására a FileNew… ( Ctrl+N ) menüpontot szolgál, amelynek kiválasztása az alábbi ábrán látható ablakot eredményezi.

D.1. ábra - Új dokumentum létrehozása az <oXygen/>-ben

Új dokumentum létrehozása az <oXygen/>-ben

A középső fastruktúrában a New Document alatt felkínált lehetőségek közül kell a sémáknak megfelelők (XML Schema, RELAX NG Schema – XML, RELAX NG Schema – Compact, Schematron) valamelyikét kiválasztani. Az új sémadokumentum a Create gombra való kattintás után jön létre. A létrehozandó dokumentum testreszabásához rendelkezésre állhat a Customize gomb is, de ezt nem minden lehetőséghez biztosítja a program.

Sémadokumentumok szerkesztése

Sémadokumentumok szerkesztését számos módon segíti a program, itt csupán néhányat sorolunk fel. Nélkülözhetetlen funkciója a gépelés közbeni automatikus kiegészítés. Nagyon hasznos a súgója, amely az egérmutató alatti elemről vagy tulajdonságról egy kis szövegdobozban jelenít meg egy rövid leírást. Lehetővé teszi sémakomponensek (akár több dokumentumot érintő) átnevezését.

A W3C XML Schema esetén az <oXygen/> a sémákat diagram formájában is megjeleníti, amely a Design lapon érhető el. Az ábra egyrészt hasznos segítséget jelent a séma áttekintéséhez és megértéséhez, másrészt lehetővé teszi a séma vizuális szerkesztését.

D.2. ábra - Séma diagram megjelenítése az <oXygen/>-ben

Séma diagram megjelenítése az <oXygen/>-ben

Dokumentáció előállítása

A ToolsGenerate DocumentationSchema Documentation… ( Alt+Shift+U ) menüpont kiválasztásával állítható elő dokumentáció sémákból, amelyhez több formátum is választható (HTML, PDF, DocBook).

D.3. ábra - Dokumentáció előállítása az <oXygen/>-ben

Dokumentáció előállítása az <oXygen/>-ben

D.4. ábra - Az <oXygen/> által előállított sémadokumentáció HTML-ben

Az <oXygen/> által előállított sémadokumentáció HTML-ben

Dokumentumok érvényesítése

Ha egy dokumentumhoz tartozik (XML Schema esetén az xsi:noNamespaceSchemaLocation vagy az xsi:schemaLocation tulajdonsággal megadott) séma, akkor a Validate ikonra történő kattintással vagy a Ctrl+Shift+V billentyűkkel ellenőrizhető az érvényesség. (Az OptionsPreferences… menüpont kiválasztásával elérhető Preferences ablakban beállítható automatikus érvényesítés.)

Ha a dokumentumhoz nem tartozik séma, akkor a Validate ikon jobb oldalán lenyitható menüben a Validate with… menüpont kiválasztásával végezhető érvényesítés, amelyhez meg kell adni egy sémadokumentumot.

Ha a dokumentumhoz egy sémát szeretnénk hozzárendelni, akkor kattintsunk a Associate Schema… ikonra.

Irodalomjegyzék

[XML-C14N] Boyer, John. Canonical XML Version 1.0. W3C. 2001.

[JSR 222] JavaTM Architecture for XML Binding (JAXB) 2.0. Oracle Corporation.

[RELAX NG] Clark, James és Makoto, Murata. RELAX NG Specification. OASIS. 2001.

[RELAX NG Errata] Clark, James. RELAX NG Specification Errata.

[RELAX NG DTD] Clark, James és Makoto, Murata. RELAX NG DTD Compatibility. OASIS. 2001.

[RFC 3066] Alvestrand, H.. Tags for the Identification of Languages. IETF. 2001.

[RFC 3986] Berners-Lee, T., Fielding, R., és Masinter, L.. Uniform Resource Identifier (URI): Generic Syntax. IETF. 2005.

[Schematron] ISO/IEC 19757-3:2006. Information technology — Document Schema Definition Language (DSDL) — Part 3: Rule-based validation — Schematron. ISO. 2006.

[XML 1.0] Bray, Tim, Paoli, Jean, Sperberg-McQueen, M., Maler, Eve, és Yergeau, François. Extensible Markup Language (XML) 1.0. Fifth Edition. W3C. 2008.

[XML Names] Bray, Tim, Hollander, Dave, Layman, Andrew, Tobin, Richard, és Thompson, Henry. Namespaces in XML 1.0. Third Edition. W3C. 2009.

[XPath] Clark, James és DeRose, Steve. XML Path Language (XPath) Version 1.0. W3C. 1999.

[XML Schema: Primer] Fallside, David és Walmsley, Priscilla. XML Schema Part 0: Primer. Second Edition. W3C. 2004.

[XML Schema: Structures] Thompson, Henry, Beech, David, Maloney, Murray, és Mendelsohn, Noah. XML Schema Part 1: Structures. Second Edition. W3C. 2004.

[XML Schema: Datatypes] Biron, Paul és Malhotra, Ashok. XML Schema Part 2: Datatypes. Second Edition. W3C. 2004.