#The XQuery and XPath Data Model (XDM)
XPath, XSLT, and XQuery all operate on the same abstract view of XML documents called the XDM (XQuery and XPath Data Model). Understanding the XDM is like understanding how LINQ sees IEnumerable<T> — it's the mental model that makes everything else click.
#Why It Matters
When you write XPath like /order/items/item, you're not doing string matching. You're navigating a typed tree defined by the XDM. The XDM defines:
-
What kinds of nodes exist
-
How they relate to each other (parent, child, sibling, ancestor, descendant)
-
What values they have
-
How sequences work
#Sequences
The fundamental data type in XDM is the sequence — an ordered list of items. This is directly analogous to IEnumerable<T> in .NET.
Key rules:
-
Every value is a sequence (even a single number — it's a sequence of length 1)
-
Sequences are flat — no nesting (unlike JSON arrays)
-
The empty sequence
()is like an empty enumerable
(1, 2, 3) => a sequence of three integers
"hello" => a sequence of one string
() => the empty sequence
(1, (2, 3), 4) => flattened to (1, 2, 3, 4)If you've used LINQ's SelectMany to flatten nested collections, the XDM does this automatically.
#Atomic Types
The XDM has a rich type system — much richer than JSON's string/number/boolean/null:
|
XDM Type |
.NET Equivalent |
JSON Equivalent |
|---|---|---|
|
|
|
string |
|
|
|
number |
|
|
|
number |
|
|
|
number |
|
|
|
boolean |
|
|
|
string (convention) |
|
|
|
string (convention) |
|
|
|
not supported |
|
|
|
string (convention) |
|
|
Qualified name |
not supported |
Notice that dates, times, and URIs are first-class types — not strings that happen to look like dates. This means XPath can compare dates, add durations, and sort by time without parsing strings.
#Nodes and Their Properties
Each node in the XDM has:
-
Identity — two nodes can have the same content but be different nodes
-
Type — document, element, attribute, text, comment, processing instruction, namespace
-
Name — elements and attributes have qualified names (namespace + local name)
-
String value — the text content
-
Typed value — the value cast to its schema type
-
Children — for document and element nodes
-
Attributes — for element nodes
-
Parent — every node except the document root has one
#The Tree, Visualized
Document
└── Element: order (id="12345")
├── Attribute: id = "12345"
├── Element: customer
│ └── Text: "Acme Corp"
└── Element: items
├── Element: item (sku="WIDGET-1")
│ └── Attribute: sku = "WIDGET-1"
└── Element: item (sku="GADGET-2")
└── Attribute: sku = "GADGET-2"XPath navigates this tree. XSLT transforms it. XQuery queries and constructs from it. They all see the same XDM.