Validation Context

Validation makes sense only in a given context. Validating a name element inside a user element checks that it contains first and last elements; while validating a name element inside an article element checks that it contains a string.

In addition to keeping track of the types of variables , the static environment contains a validation context. Initially, this context is set to global. During static analysis, when an element constructor with a given name is entered, the context is extended by that element name within the constructor. For example, consider the query in Listing 4.10, which constructs a user element, omitting the first name if it is too long, or the rating if it is too low.

Listing 4.10 Validation Context Specified by Lexical Scope of Constructors
 let $first := "Mary",     $last := "Doe",     $rating := "A" return   <user id="U02">     <name>        { if (fn:string-length($first) > 10) then () else                                         <first>{ $first }</first> }        <last>{ $last }</last>     </name>     { if ($rating > "C") then () else <rating>{ $rating }</rating> }   </user> 

Here, the user element is validated in the global context, the name and rating elements are validated in the context user , and the first and last elements are validated in the context user/name .

It would be impossible to determine static types if the context used to validate an element constructor was not known statically; thus, the validation context is part of the static environment. It is determined by lexical scope, not by the nesting of elements in the final document. When there is a mismatch between the two, this may be fixed by adding an explicit context to a validate expression. For example, Listing 4.11 shows a variant of the query in Listing 4.10.

Listing 4.11 Validation Context Specified Explicitly in Validate Expression
 let $first := validate context user/name { <first>Mary</first> },     $last := validate context user/name { <last>Doe</last> },     $rating := validate context user { <rating>A</rating> } return   <user id="U02">{     <name>{       if (string-length($first) > 10) then () else $first,       $last     }</name>,     if ($rating > "C") then () else $rating   }</user> 

Since the first , last , and rating elements are no longer lexically nested within the user and name elements, the validation context must be explicitly given when the elements are constructed . This guarantees that validation labels the elements with the appropriate types.

Lexical nesting and evaluation order may also differ in the presence of a function call. Again, an explicit context must be given in this case. The function shown in Listing 4.12 takes the locally declared elements first and last in the context user/name .

Listing 4.12 Validation Context in Function Call and Body
 define function make_name (   $first as element(user/name/first),   $last as element(user/name/last) ) as element(user/name) {   validate context user {     <name>{       if (string-length($first) > 10) then () else $first,       $last     }</name>   } } let $rating := "A" return   <user>{     make_name(       validate context user/name { <first>Mary</first> },       validate context user/name { <last>Doe</last> }     ),     if ($rating > "C") then () else <rating>{ $rating }</rating>   }</user> 

The validate expressions above are used to supply context for the name element in the function body, and the first and last elements in the function call.

You might conclude from this discussion that it is easiest always to construct elements in the proper context. One way to ensure this is to prefer global declarations to local declarations when designing a schema, since a globally declared element requires no context for validation.



XQuery from the Experts(c) A Guide to the W3C XML Query Language
Beginning ASP.NET Databases Using VB.NET
ISBN: N/A
EAN: 2147483647
Year: 2005
Pages: 102

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net