XQuery/Validating a document

Motivation edit

You want to validate a document using an XML Schema.

Method edit

Note: Validation is a very complex topic. eXist come with default setting that may prevent files from being added that are associated with a namespace once a schema is saved in the registry. Please be aware of these factors that are documented here.

eXist supports a validation module that includes a validate() function to validate an XML file against a grammar file such as an XML Schema.

validation:validate($input-doc as item(), $schema-uri as xs:anyURI) as xs:boolean

where: $input-doc is the document you want to validate $schema-uri is a URI to the XML Schema you want to use to validate the document. Note that this must be of type xs:anyURI.

This function return a single true/fales value which is true if the document is valid according to the XML Schema.

Sample Code edit

xquery version "1.0";

let $doc :=
<root>
   <element>test</element>
</root>

let $schema := '/db/test/validate/schema.xsd'

(: you must run this every time the XML Schema file changes! :)
let $clear := validation:clear-grammar-cache()

let $result :=
if (validation:validate($doc, $schema))
  then "PASS"
  else "FAIL"
  
return
<results>
   {$result}
</results>

Sample XML Schema edit

Here is a sample XML Schema to validate a very small XML file. In eXist 1.3 only XML files with a namespace are supported.

<xs:schema 
   xmlns="http://example.com" 
   xmlns:xs="http://www.w3.org/2001/XMLSchema" 
   targetNamespace="http://example.com" 
   elementFormDefault="qualified">
    <xs:element name="root">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="my-data"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

There are two important points about this XML Schema.

The targetNamespace="http://example.com" attribute indicates that this XML Schema is targeting the http://example.com namespace.


The elementFormDefault="qualified" attribute indicates that as the XML parser reads the root of the file, the target namespace should be used.

Without these two attributes the validation will not work.

Sample XML file to be Validated edit

<root xmlns="http://example.com">
    <my-data>test</my-data>
</root>

Getting Error Messages edit

The validate() function only returns a simple boolean true/false value. If there is an error in your XML file this function is not very useful at finding the errors. To assist with this process their is another function called validate-report(). It has the same arguments:

validation:validate-report($input-doc, $schema-uri)

The result can be modified to be the following:

let $result :=
 if ( validation:validate($input-doc, $schema-uri) )
   then "The XML File is Valid"
   else (
      "The XML File is Not Valid",
      validation:validate-report($input-doc, $schema-uri)
   )

References edit

Documentation on validation in eXist