Az XDM egészen pontosan az XQuery 1.0 és az XPath 2.0 közös adatmodellje ( kiegészülve az XSLT 2.0-val). A W3C skáláján végigérve 2010. decemberében vált ajánlássá, felváltva a 2007-ben megjelent korábbi verzióját. Alapvető célja egyrészt, hogy meghatározza egy XSLT vagy XQuery feldolgozó számára a bemeneten ékező XML dokumentum információtartalmát, másrészt pedig meghatározza az elfogadható kifejezéseket az XSLT, XQuery és XPath nyelvek számára.
Definíció szerint egy nyelv zárt az adatmodellre nézve, ha a nyelv bármely kifejezésének az értéke garantáltan az adatmodellben marad. Az XSLT 2.0, XQuery 1.0 és az XPath 2.0 mind zárt a következőekben ismertetett adatmodellre nézve, melynek alapja a már korábban ismertetett InfoSet ajánlás 2004-ben kiadott második verziója kiegészítve az XML Schema által használt típushierarchiával.
Hasonlóan az InfoSet-hez, az XDM meghatározza, hogy milyen információ érhető el a dokumentum alapján, de nem határoz meg semmilyen nyelvi kötést vagy felületet az adatok eléréséhez. A korai 1.0-s verzióhoz képest az adatmodell bővült a típusos atomi értékekkel és a szekvenciákkal (a halmazt leváltva).
A szekvencia nem más, mint elemek kollekciója. Az új fogalomrendszerben pedig az elem vagy csomópont vagy atomi érték.
Szekvencia típus t (kivonatolva) t ::= empty-sequence() | item occ occ ::= + | * | ? | ε item ::= atomic | node | item() node ::= element(name) | text() | node() | ... name ::= * | QName atomic ::= integer | string | double | ...
Fontos megjegyezni, hogy a feldolgozás során mindig van típusa a szekvenciának (a példában először a legspecifikusabb szerepel):
42 => integer, item()
<x>foo</x> => element(x), item()
() => empty-sequence(),integer*
("foo", "bar") => string+, item()*
(<x/>, <y/>) => element(*)+, node()*A szekvenciák nem tartalmazhatnak további szekvenciákat, ha mégis összefűzzük őket, akkor az eredmény mindig ki lesz "laposítva" - beágyazott szekvencia nem létezhet.
(0, (), (1, 2), (3)) ≡ (0, 1, 2, 3) (0, 1) ≡ (1, 0)
Emellett nincs különbség az egy elemű szekvencia és az elem között. Egy elem egyben egy egyelemű szekvencia is! Nagyon fontos különbség az 1.0-s verzió halmaz filozófiájához képest, hogy míg 1.0-ban emiatt egy elem csak egyszer szerepelhetett a halmazban, addig ebben az adatmodellben a szekvencia használatával egy elem már többször is bekerülhet - az identitását megőrzi.
Az atomi érték az atomi típus tartományából való, ahol az atomi típusnak számít a primitív típus vagy más atomi típusból megszorítással származtatottak. A típushierarchia legtetején az untypedAtomic áll, amely akkor kerül legtöbbször alkalmazásra, ha nem validált XML dokumentumból kapjuk a tartalmat. Ekkor a kifejezés típusa alapján megpróbálja implicit módon típus kényszeríteni (ami egyben hasznos is és veszélyes is):
"42" + 1 ⇒ type error (compile time) <x>42</x> + 1 ⇒ 43.0E0 (: double :) <x>fortytwo</x> + 1 ⇒ conversion error (runtime)
A szekvenciák miatt nagyon fontos még a csomópontok identitása. Az adatmodell minden példányában minden egyes csomópont egyedi. (Ellentétben az atomi értékekkel, amelyeknek nincs identitásuk. Az '5' karakter mindenhol ugyanazt az ötöt fogja jelenteni, mint egész szám.)
<x>foo</x> is <x>foo</x> ⇒ false() <x>foo</x> = <x>foo</x> ⇒ true()
Az egész feldolgozás során pedig az egyik legfontosabb definíció a dokumentumsorrend: az adott lekérdezés/transzformáció során elérhető csomópontok között értelmezett, azt adja meg, hogy hogyan jelennek meg ezen csomópontok a dokumentum szerializált változatában. Egy csomópont dokumentumsorrendben megelőz egy másikat, ha az általános egyedek helyettesítése után az XML reprezentációjának első karaktere megelőzi a másikét a dokumentumban. További jellemzői:
A gyökér csomópont az első a sorrendben.
Az elem csomópontok így mindig megelőzik a gyermekeiket és leszármazottaikat a sorrendben.
Az testvér csomópontok rendezése a nyitó címkék sorrendjének megfelelően /nem ábécé vagy egyéb/
A gyermekek és leszármazottak hamarabb vannak, mint a testvérek.
A tulajdonság- és névtércsomópontok megelőzik azt a csomópontot, melyhez tartoznak.
Egy elemcsomóponthoz tartozó névtércsomópontok megelőzik a tulajdonság csomópontokat.
A tulajdonság- és névtércsomópontok relatív elrendezése implementációfüggő.
Az adatmodell példányai alapvetően kétféle XML dokumentumból készíthető el:
Jól-formázott XML dokumentumok, melyek megfelelnek az XML névtér specifikációnak,
Validált XML dokumentumok, itt csak a DTD-vel és XML Schema-val szemben validáltak fogadhatóak el.
Az első esetben az InfoSet alapján készíthető el az adatmodell, melyben már az entitáshivatkozásoknak fel kell lennie oldva, míg a második esetben a korábban már említett PSVI alapján történik. Az XDM-ben az XML dokumentumok modellezése olyan fákkal, melyekben az alábbi fajta csomópontok szerepelhetnek:
Gyökércsomópont:
A fa gyökere, gyermekei a dokumentum gyökérelemét reprezentáló elem csomópont, valamint a dokumentumban azt megelőző és követő megjegyzéseket és feldolgozó parancsokat reprezentáló csomópontok. Sztring értéke az összes leszármazott szöveg csomópont sztring értékének dokumentum sorrendben történő összefűzésével adódik. Nincs kiterjesztett neve.
Elemcsomópont:
Minden a dokumentumban szereplő elemnek egy elemcsomópont felel meg a fában. A sztringérték úgy határozandó meg, mint a gyökércsomópont esetében.
Van kiterjesztett nevük. Minden elemcsomóponthoz hozzárendelt névtércsomópontok egy halmaza. Minden egyes olyan névtér-előtaghoz, amelynek hatáskörében van az adott elem, egy névtércsomópont feleltetődik meg. Ha az elem alapértelmezett névtér-deklaráció hatáskörébe esik, annak is egy névtércsomópont megfeleltetése.
Szövegcsomópont:
Szövegcsomópontot soha nem előz meg vagy követ másik szövegcsomópont. A sztringérték értelemszerű (legalább egy karakterből áll). A dokumentumelemen (gyökérelemen) kívüli whitespace karakterek nem jelennek meg szövegcsomópontokként. Nincs kiterjesztett nevük.
Attribútum csomópont:
Legfontosabb jellemzőjük, hogy nem gyermekei az elemcsomópontoknak. A tulajdonság-csomópontoknak szülői azok az elemcsomópontok, melyekhez tartoznak. Sztringértékük a normalizált tulajdonságérték Van kiterjesztett nevük.
Névtércsomópont:
Szintén nem gyermekei az elemcsomópontoknak Hasonlóan, a névtércsomópontoknak szülői azok az elemcsomópontok, melyekhez tartoznak. Sztringértékük a megfelelő névtér URI. Ha a névtér-deklarációban adott URI relatív, akkor ez a sztringérték implementációfüggő!
Van kiterjesztett nevük:
A lokális rész a névtér-előtag (alapértelmezett névtérnél az üres sztring)
A névtér URI null
Feldolgozási utasítás-csomópont
Megjegyzéscsomópont
Az elemcsomópontok esetén érdemes megnézni az elérhető tulajdonságokat:
node-name tag: az elem neve,
parent: szülő elem, lehet üres is,
children: gyermekek, lehet üres is,
attributes: az adott elem attribútumai
string-value: a tartalom szerinti összefűzése az összes sztingértéknek,
typed-value: az elem értéke (CSAK validálás után)
typed-name: a hozzerendlt típus neve a validáció során
Figyeljük meg az értékek változását az alábbi példán:
<x> 04<!-- unexpected comment -->2 </x>
A csomópont tulajdonságai validálás előtt:
node-name: x,
parent: ()
children: (t1; c; t2),
attributes: -
string-value: <LF> 042<LF>
typed-value: <LF> 042<LF>
typed-name: untypedAtomic
A csomópont tulajdonságai validálás után:
node-name: x,
parent: ()
children: (t1; c; t2),
attributes: -
string-value: <LF> 042<LF>
typed-value: 42
typed-name: integer
Eltérések a DOM–tól
A DOM adatmodellel ellentétben nem követhetik egymást szövegcsomópontok és az attribútumcsomópontoknak nincs szülője. A CDATA szakaszok is szövegcsomópontokként jelennek meg. Ezen felül valamennyi egyedhivatkozás helyettesítésre került, így azok nem jelennek meg önálló csomópontokként.
A névterek ( a DOM-tól eltérően, ahol csak az explicit módon megadott névtér-deklarációk jelennek meg) minden csomópontnál megjelennek.