The XQuery Data Model (XDM) is more precisely a common data model for XQuery 1.0 and XPath 2.0 (extended with XSLT 2.0). It became a W3C recommendation in December of 2010. thus replacing its previous version appeared in 2007. The primary goal of the XDM is to provide the required information set from an input XML for an XSLT or XQuery engine. Moreover, it provides the acceptable expressions for the XSLT, XQuery and XPath languages.
By definition, a language is closed for its data model if any of the language’s expressions value remains inside the data model. The XSLT 2.0, XQuery 1.0 and the XPath 2.0 are all closed for the forthcoming data model which is based on the previously mentioned Infoset recommendation from 2004 extended with the type hierarchy used by XML Schema.
Like the Infoset, the XDM defines all the information that could be collected from an XML document but does not impose any language binding or interface for reaching the data. The early 1.0 version was extended by the typed atomic values and the term of the sequences (replacing the set term).
A sequence is a collection of elements. In this new notation, an element could be a node or an atomic value.
Sequence type t (abstract) t ::= empty-sequence() | item occ occ ::= + | * | ? | ε item ::= atomic | node | item() node ::= element(name) | text() | node() | ... name ::= * | QName atomic ::= integer | string | double | ...
Important to know that during the parsing every sequence has a type always. In the following example the most general type comes first:
<x>foo</x> => element(x), item()
() => empty-sequence(),integer*
("foo", "bar") => string+, item()*
(<x/>, <y/>) => element(*)+, node()*Sequences cannot hold sequences inside. When we merge them the result always a flat sequence will be. Nested sequences cannot exists.
(0, (), (1, 2), (3)) ≡ (0, 1, 2, 3) (0, 1) ≡ (1, 0)
Moreover, there is no difference between an element and a one sized sequence. An element is also a sequence! An other important difference form the 1.0 version - which originates for the set theory where one element could exist only one times in a set, that in 2.0 the sequences are allowing to include one element more than one times in the sequence and its identity is reserved.
An atomic value is derived from its domain where the atomic type could be a primitive type or its derivatives - created by restrictions. The root of the type hierarchy is the untypedAtomic, which is utilized when we wok with an unvalidated XML document. In that case, the runtime engine tries to cast it to the most specific type automatically (which could be an advantage but imposes risks too):
"42" + 1 ⇒ type error (compile time) <x>42</x> + 1 ⇒ 43.0E0 (: double :) <x>fortytwo</x> + 1 ⇒ conversion error (runtime)
Along with the sequences, the node identity play an important role in XDM. In every instance of the data model every node has its own identity. (Contrary with the atomic values whose identity is not definable.) The character '5' will mean the same five as a number everywhere in the document.
<x>foo</x> is <x>foo</x> ⇒ false() <x>foo</x> = <x>foo</x> ⇒ true()
During the processing the most important term is thedocument order: its interpreted inside the nodes affected by a query or transformation and defines the order of the elements in the serialized version of the document. It is corresponding to the order in which the first character of the XML representation of each node occurs in the XML representation of the document after expansion of general entities. Further characteristics:
the root node will be the first node.
Element nodes occur before their children.
Siblings are in order of the occurrence of their start-tag in the XML /not alphabetical or any other/
Children and descendants are always before as siblings.
The attribute nodes and namespace nodes of an element occur before the children of the element.
The namespace nodes are defined to occur before the attribute nodes.
The relative order of namespace nodes and attribute nodes are implementation-dependent.
The instances of the data model could be created basically from two types of XML documents:
Well-formed XML documents, fulfilling the namespace definitions,
Validated XML documents, using only DTD or XML Schema.
In the first case, the data model is based on the InfoSet where general entities are resolved. In the second case, the above mentioned PSVI is used fo it. In the XDM the XML document is modeled by tress with the following node types only:
Root Node:
The root node is the root of the tree. A root node does not occur except as the root of the tree. The element node for the document element is a child of the root node. The root node also has as children processing instruction and comment nodes for processing instructions and comments that occur in the prolog and after the end of the document element. The string-value of the root node is the concatenation of the string-values of all text node descendants of the root node in document order. The root node does not have an expanded-name.
Element Nodes:
There is an element node for every element in the document. An element node has an expanded-name computed by expanding the QName of the element specified in the tag in accordance with the XML Namespaces Recommendation. Its string value is the same as the Root node.
The namespace URI of the element's expanded-name will be null if the QName has no prefix and there is no applicable default namespace.
Text Nodes:
Character data is grouped into text nodes. As much character data as possible is grouped into each text node: a text node never has an immediately following or preceding sibling that is a text node. The string-value of a text node is the character data. A text node always has at least one character of data. A text node does not have an expanded-name.
Attribute Nodes:
Each element node has an associated set of attribute nodes; the element is the parent of each of these attribute nodes; however, an attribute node is not a child of its parent element. An attribute node has a string-value. The string-value is the normalized value. An attribute whose normalized value is a zero-length string is not treated specially: it results in an attribute node whose string-value is a zero-length string.
Namespace Nodes:
Each element has an associated set of namespace nodes, one for each distinct namespace prefix that is in scope for the element (including the XML prefix and one for the default namespace if one is in scope for the element. The element is the parent of each of these namespace nodes; however, a namespace node is not a child of its parent element.
Elements never share namespace nodes: if one element node is not the same node as another element node, then none of the namespace nodes of the one element node will be the same node as the namespace nodes of another element node.
A namespace node has an expanded-name: the local part is the namespace prefix (this is empty if the namespace node is for the default namespace); the namespace URI is always null. The string-value of a namespace node is the namespace URI that is being bound to the namespace prefix; if it is relative, it must be resolved just like a namespace URI in an expanded-name.
Processing Instruction Nodes
Comment Nodes
Its good to know what are the available properties for these nodes:
node-name tag: name of the element,
parent: parent element, could be empty,
children: child element, could be empty,
attributes: all the attributes,
string-value: the aggregated value,
typed-value: the value of the element (after validation ONLY)
typed-name: the assigned type's name during the validation
The following example show how data types are changing:
<x> 04<!-- unexpected comment -->2 </x>
The attributes of the element before validation:
node-name: x,
parent: ()
children: (t1; c; t2),
attributes: -
string-value: <LF> 042<LF>
typed-value: <LF> 042<LF>
typed-name: untypedAtomic
The attributes of the element after validation:
node-name: x,
parent: ()
children: (t1; c; t2),
attributes: -
string-value: <LF> 042<LF>
typed-value: 42
typed-name: integer
Differences from the DOM
It is prohibited to follow text nodes each other and attribute nodes have not got a parent. CDATA sections are appearing as a text node. Finally, all the entity references are resolved, so they cannot appear as nodes.
Namespaces are always present at each node, not like in DOM where only explicit namespaces are in use.