This page is a quick presentation on how to use Zorba with XMLSchema type information.
In order to use XMLSchema type information in a query a schema file needs to be imported. Note the URI must match the target namespace of schema file.
import schema namespace r = "http://example" at "example.xsd";
For a full example see the Example 1 below.
Note: for simplicity, the examples on this page make use of the "at <filename>" clause of import schema
to explicitly load a specific schema file. However, when developing XQuery applications, it is usually better to omit this clause, and make use of Zorba's extensive URI-resolution mechanisms to load schema documents by URI. For details on this, see URI Resolvers.
Use validate expression to validate an untyped document against an XMLSchema.
validate {$untypeDoc}
For a full example see the Example 1 below.
The XQuery script example.xq
:
import schema namespace r = "http://example" at "example.xsd"; import module namespace file = "http://expath.org/ns/file"; let $untypeDoc := fn:parse-xml(file:read-text("example.xml")) let $validatedDoc := validate {$untypeDoc} return $validatedDoc
Assuming there is an example.xsd
file with this content:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://example" xmlns="http://example" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xs:element name="a" type="TypeA"/> <xs:complexType name="TypeA"> <xs:sequence> <xs:element name="b" maxOccurs="unbounded" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:schema>
And this example.xml
instance XML document:
<a xmlns="http://example">
<b>Hello world!</b>
</a>
Zorba can execute the query to get the result:
$ zorba --trailing-nl -i -f -q example.xq <?xml version="1.0" encoding="UTF-8"?> <a xmlns="http://example"> <b>Hello world!</b> </a>
Using the schema module it is possible to find out the QName of a certain schema type.
Example 1 can be adapted to the following:
import schema namespace r = "http://example" at "example.xsd"; import module namespace file = "http://expath.org/ns/file"; import module namespace schema = "http://www.zorba-xquery.com/modules/schema"; let $untypeDoc := fn:parse-xml(file:read-text("example.xml")) let $validatedDoc := validate {$untypeDoc} return let $qname := schema:schema-type($validatedDoc/r:a) return ( fn:prefix-from-QName($qname), fn:local-name-from-QName($qname), fn:namespace-uri-from-QName($qname) )
Output:
$ zorba --trailing-nl -i -f -q example.xq <?xml version="1.0" encoding="UTF-8"?> TypeA http://example
The C++ Zorba API can be used by an application to validate a document and later passed as a valid input into another query.
In the Example 2 first loadProlog method on the static context was used to import the required schema file and than validate method was called to get the new validated item.
sc->loadProlog("import schema namespace s='http://test.org' at 'schema.xsd';", hints);
sc->validate(lChild, vItem);
#include <iostream> #include <sstream> #include <zorba/zorba.h> #include <zorba/store_manager.h> #include <zorba/serializer.h> #include <zorba/singleton_item_sequence.h> #include <zorba/zorba_exception.h> using namespace zorba; void printItem(Item& lChild, String pre); void printIter(Iterator_t lIter, String pre); void printIter(Iterator_t lIter, String pre) { lIter->open(); Item lChild; while (lIter->next(lChild)) { printItem(lChild, pre); } lIter->close(); } void printItem(Item& lChild, String pre) { Item lNodeName; lChild.getNodeName(lNodeName); std::cout << pre << "node " << lNodeName.getStringValue() << " -type " << lChild.getType().getStringValue() << std::endl; Iterator_t lAttrIter = lChild.getAttributes(); lAttrIter->open(); Item lAttr; while (lAttrIter->next(lAttr)) { Item lNodeName; lAttr.getNodeName(lNodeName); std::cout << pre << " @" << lNodeName.getStringValue() << "=" << lAttr.getStringValue() << " -type " << lAttr.getType().getStringValue() << std::endl; } lAttrIter->close(); Iterator_t lChildIter = lChild.getChildren(); printIter(lChildIter, pre + " "); } bool example_12(Zorba* aZorba) { // without validation String query = "<a xmlns='http://test.org'><b attr='1'/><b attr='2'/></a>"; XQuery_t lQuery1 = aZorba->compileQuery(query); Iterator_t lIterator1 = lQuery1->iterator(); printIter(lIterator1, " "); //with validation XQuery_t lQuery2 = aZorba->compileQuery(query); Iterator_t lIterator2 = lQuery2->iterator(); lIterator2->open(); Item lChild; lIterator2->next(lChild); StaticContext_t sc = aZorba -> createStaticContext(); const Zorba_CompilerHints_t hints; sc->loadProlog("import schema namespace s='http://test.org' at 'schema.xsd';", hints); Item vItem; std::cout << "Validate: " <<std::endl; std::cout.flush(); bool vres = sc->validate(lChild, vItem); std::cout << " res : " << (vres ? "true" : "false") << std::endl; std::cout.flush(); printItem(vItem, " "); lIterator2->close(); return true; } int main(int argc, char **argv) { std::cout << "Start" << std::endl; std::cout.flush(); void* lStore = StoreManager::getStore(); Zorba *lZorba = Zorba::getInstance(lStore); bool res = false; std::cout << "executing example 12" << std::endl; res = example_12(lZorba); if (!res) return 1; std::cout << std::endl; lZorba->shutdown(); StoreManager::shutdownStore(lStore); std::cout << "Done!" << std::endl; std::cout.flush(); return 0; }
Output: