This section describes the process which interprets instance documents in terms of an abstract document model. The process has two stages. First, several initial lexical transformations normalize forms in the instance document and arrange the declarations in contexts. Then a collection of valuation operators generate the respective abstract document model.

Lexical Transformations

The interpretation process presumes several primitive lexical transforms between an instance document, which appears in the simplified concrete syntax, and the instance document as expressed in the abstract syntax.

unprefixed generic identifiers and attribute names are transformed into qualified names with null prefixes

NCName ==> (qn: null LocalPart dci0)

The exceptional case of the default namespace prefix is transformed into a qualified name with that as the prefix and anull local part

xmlns ==> (qn: xmlns null dci0)

declarations are collected into declaration context tree. The root of the tree is the internal subset. Each external entity adds a declaration context as a branch to this tree. This is true of both the external subset and any entity incorporated through an external parameter entity, Nested parameter entity references introduce further branches which extend from the context in which they are referenced. Each declaration context is extended with a context identifier which is generated by appending a per-context index to the identifer of its containing context. The root context identifier is '0'. Qualified names are extended with the respective declaration context identifier. For example

<!DOCTYPE doc [ <!ELEMENT x ANY> <!ATTLIST x a CDATA "s"> ]>
<x/>

==>

(:doc (:qn null 'doc')
(:dcl (:ed (:qn null 'x' '0') ANY) (:ad (:qn null 'x' '0') (:a (:qn null 'a' '0')))))
(:e (:qn null 'x' '0') () () ()))

Were a parameter entity involved, the abstract expression would exhibit nested declaration contexts

<!DOCTYPE doc [ <!ELEMENT x ANY>
<!ENTITY %p SYSTEM "data:,<!ATTLIST x a CDATA 's'>">
%p;
]>
<x/>

==>

(:doc (:qn null 'doc')
(:dcl (:ed (:qn null 'x' '0') ANY) (:dcl (:ad (:qn null 'x' '0.0') (:a (:qn null 'a' '0.0'))))))
(:e (:qn null 'x' '0') () () ()))

Valuation Operators

The valuation operators depend on several primitives.

declaration context equivalence

dci0 ==l (dci1 + Character*)


dci0 < dci1

qualified name equality
p0 ==l p1, l0 ==l l1, ( dci0 < dci1 | dci1 < dci0)
(:qn p0 l0 dci0) ==p (:qn p1 l1 dci1)

Where the encoding xmlns appears as an attribute value, the valuation is the qualified name with the xmlns prefix and a local part null.
QN[[ (:qn null xmlns ) ]]
==> (qn: xmlns, null )

All other encoded names evaluate to qualified names
QN[[ (:qn null l ) ]]
==> (qn: null, l )
QN[[ (:qn p l ) ]]
==> (qn: p, l )


[[<!ATTLIST (pi li vi), (xmlns, pj), u)> (ED, (pi, li, u) EU)]] ==> EU' = (EU, (pi, u)) in (TEu (I[[(pi, li)]], EU') (TAu, (I[[(pi, li)]], EU'), (I[[(xmlns, li, u)]], EU') )

nse0 = ( (xmlns {xmlns}), (xml {}), (|| {}) )

intern DTD : ID == ( DoctypeDecl NamespaceEnvironment ) ==> Schema


Document valuation transforms a concrete document instance into a abstract instance by transforming the declarations into a schema, interning the document name in the context of the schema, and transforming the document element in the context of the schema.
DOC[[ (:doc q0 dcl0 e0) ]] s0 nse0
==> s1 == S[[ dcl0 ]] s0 nse0
(doc (Ud[[ q0]] s1 nse0), s1, (E[[ e0 ]] s1 nse0) )


UN ::= (QualifiedName X Schema X NamespaceEnvironment) ==> UniversalName
The qualified document type name is transformed in the context of the global namespace environment and the document schema. If the prefix is bound globally, the respective universal name applies. otherwise the universal name identifier of that element for which the original qualified name matches is used.
UNd[[ (:qn p0 l0) ]] (s (ed (un nsn0 l0 p0) em0) . ed*) nse0
==> let u0 == resolveQName( (:qn p0 l0) nse0)
in isNull(u0) ->
let ed0 == findElementDeclaration( (:qn p0 l0) s0)
in cases (ed0) isNull(ed0) -> |/ [] isElementDeclaration( u1, em0, u* ) -> u1 end
[] u0

S ::= (DeclarationContext X Schema X NamespaceEnvironment) ==> Schema
The document type declaration is transformed by coalescing attribute declarations with the matching element declarations, recognizing namespace bindings and propagating these bindings through the imputed element content hierarchy.

The terminal valuation completes the process once all concrete declarations have been translated.
S[[ dcx0 ]] s0 nse0
==> s0

multiple element declarations with the same qualified name identifier are an error
qn0 == qn1
|-
S[[ ( (:ed qn0 qn*), (:ed qn1 qn*) . dcl*)]] sc nse
==> error

A new element declaration instance is introduce by the presence of an element declaration form. The element identifier remains initially a qualified name.
S[[ (:dcx (:ed qn0 qn*) . dcl*) ]] (sc, md*) nse0
==> S[[ (:dcx (:ed qn0 qn*) . dcl*) ]] (sc, (ed, QN[[qn0]], (), (), nse0 ) . md* ) nse0

An exhausted element declaration form disappears.
QN[[qn0]] ==q n1 |-
S[[ (:dcx (:ed qn0 ()) . dcl*) ]] (sc, (ed, n1, n*0, n*1, nse0 ) . md* ) nse0
==> S[[ (:dcx dcl*) ]] (sc, (ed, n1, n*0, n*1, nse0 ) . md* ) nse0

The model of an existing element declaration instance is augmented based on the names in the model of an element declaration form.
QN[[qn0]] ==q n1 |-
S[[ ( (:ed qn0 (qn2 . qn*) . dcl*) ]] (sc, (ed, n1, n*0, n*1, nse0 ) . md* ) nse0
==> S[[ ( (:ed qn0 qn* . dcl*) ]] (sc, (ed, n1, (QN[[ qn2 ]] . n*0), n*1, nse0 ) . md* ) nse0

An existing element declaration is augmented based on an attribute declaration.
QN[[qn0]] ==q n1 |-
S[[ ( (:ad qn0 (qn2 . qn*) . dcl*) ]] (sc, (ed, n1, n*0, n*1, nse0 ) . md* ) nse0
==> S[[ ( (:ad qn0 qn* . dcl*) ]] (sc, (ed, n1, n*0 (QN[[ qn2 ]] . n*1), nse0 ) . md* ) nse0

In the absence of a matching element declaration an attribute declaration is ignored.
!E QN[[qn0]] ==q n1 |-
S[[ (:dcx dci ((:ad qn0 ep ) . dcl*)) ]] (sc, (ed, n1, n*0, n*1, nse0 ) . md* ) nse0
==> S[[ (:dcx dci dcl*) ]] (sc, (ed, n1, n*0, n*1, nse0 ) . md* ) nse0

A duplicate attribute declaration is ignored. Note that this filter is not sufficient to eliminate duplicate attributes: they must also be eliminated after names have been interned to account for synonyms.
QN[[qn0]] ==q n1, QN[[qn2]] ==q n2 |-
S[[ (:dcx dci (:ad qn0 (:a qn2)) . dcl*) ]] (sc, (ed, n1, n*0, (n2 . n*1), nse0 ) . md* ) nse0
==> S[[ (:dcx dci dcl*) ]] (sc, (ed, n1, n*0, (n2 . n*1), nse0 ) . md* ) nse0

An existing element declaration is augmented based on a namespace declaration.
QN[[qn0]] ==q n1 |-
S[[ (:dcx (:ad qn0 (:nsb (:qn 'xmlns' l) nsn) . dcl*) ]] (sc, (ed, n1, n*0, n*1, nse0 ) . md* ) nse0
==> let nsb0 = (P[[ l ]], NS[[nsn]]) in
let nse1 = augmentNSE(nsb0, nse0)
if
in S[[ (:dcx dcl*) ]] (sc, (ed, n1, (ed, n1, n*0, n*1, nse1 ) . md* ) nse0
end

A duplicate namespace declaration is ignored.
QN[[qn0]] ==q n1, QN[[l1]] ==q l2 |-
S[[ (:dcx dci (:ad qn0 (:nsb (:qn 'xmlns' l0) nsn)) . dcl*) ]] (sc, (ed, n1, n*0, n*1, (((nsb l0, ns) . nse0 ) . nse1 ) . md* ) nse0
==> S[[ (:dcx dci dcl*) ]] (sc, (ed, n1, n*0, n*1, (((nsb l0, ns) . nse0 ) . nse1 ) . md* ) nse0

A qualified name in the context of a matching binding is replaced by a universal name
(ed, (qn p0 l0), em0, n*0, nse0), isUniversalName(nse0(p0))
==> let u0 == nse0(p0)
in
(ed, u0, em0, n*0, nse0)

A qualified model name in the context of a matching binding is replaced by a universal name
(ed, n0, (n*0 . (qn p0 l0) . n*1), n*2, nse0), isUniversalName(nse0(p0))
==> let u0 == nse0(p0)
in
(ed, n0, (n*0 . u0 . n*1), n*2, nse0)

A qualified attribute name in the context of a matching binding is replaced by a universal name
(ed, n0, em0, (n*0 . (qn p0 l0) . n*1), nse0), isUniversalName(nse0(p0))
==> let u0 == nse0(p0)
in
(ed, n0, em0, (n*0 . u0 . n*1), nse0)

An correspondence between content model identifier and element identifier based on the presence of a namespace binding in either the containing element or the contained element leads to an identification of names and the propagation all namespace bindings from the containing element which are not shadowed by bindings in the contained element. For the purpose of comparison, the environments are combined such that, for the prefix respective the content model, the bindings in the containing element are supplemented - that is existing bindings remain visible, while for the prefix respective the contained element, the bindings are augmented - that is a binding in the contained element supercedes that of the containing element. The namespace environment of the contained element declaration is replaced with the extended
supplementNSE( nse0 nse1)(p0) ==ns extendNSE( nse0 nse1)( p1)
|-
S[[ dcx0 ]] (sc, (ed, (qn p0 l0), n*0, n*1, nse0 ) . (ed, n1, (n*0 . (qn p1 l0) . n*1), n*1, nse1) . md* ) nse0
==> let nse2 = extendNSE( nse0 nse1) in
let un0 = (nse2( p1))(qn p1 l0) in
S[[ dcx0 ]] (sc, (ed, un0, n*0, n*1, nse0 ) . (ed, n1, (n*0 . un0 . n*1), n*1, nse2) . md* ) nse0