Xquery - eXist-db
Tiziana Mancinelli
CCeH Cologne Centre for eHumanities
University of Cologne
University of Venice
AIUCD - Associazione per l’Informatica Umanistica e la Cultura Digitale
- Analyze XML documents – one, many or fragments
- Easy and efficent processing of XML documents with X-technologies
- Treat semi-structured information in a natural way – don't force your documents into the relational model (tables)
- NoSQL database
- Supports validation
Why XML databases?
- Native XML database
- optimized to store XML documents - well-suited to complex, nested, 'semi-structured' documents like TEI
- able to store any other file types
- Web server
- To serve XML, HTML, Images, JSON etc. to a client (web browser)
- XPATH, XSLT, XQuery
- Open Source Software (Java)
- Use it for free
- Contribute
Why XML databases?
http://localhost:8080/
Let's open eXist-db!
Dashboard
It is an editor to create and manage Web applications written in XQuery, XSLT, HTML, CSS, and Javascript.
eXide
- (IDE) → Integrated development environment
New Application
eXide
New Application
eXide
New Application
eXide
eXide
Go to the dashborad
Open in a browser your new app
Exist-db creates an APP or a Library
in eXide
open Index.html
As you can see, this page is not a full HTML page because eXist provides a a template system
Exist-db creates APPs and Libraries.
In fact, this one is xhtml and is not html5 because eXist will process those files.
The first tag is a DIV!
eXide
eXist-db works with templates
and all of these are activated from an attribute called data-template
for example:
data-template="templates:load-source"
eXide
eXist-db works with templates
<div data-template="app:test"/>
eXide
Open the module/app.xql
"app:test"
When a page is requested, existdb takes this page out from the db and for each data-template attribute executes the correspondent function in the module of the app or exist-db internal module.
The return value of the function will be inserted inside the tag element containing the data-template attribute
eXide
When a page is requested, existdb takes this page out from the db and for each data-template attribute executes the correspondent function in the module of the app or exist-db internal module.
The return value of the function will be inserted inside the tag element containing the data-template attribute
eXide
The first tag is a DIV!
Open the collection
Where does eXist-db store documents?
- “deconstructs” the whole XML document
- Stores single components in an efficient data structure (B+-tree)
- automatically indexes the entire
- XML structure (+ additional indexes, e.g. Lucene)
XQUERY
https://github.com/joewiz/learn-xquery
Resources
...Another language to learn!
- XML Query Language (http://www.w3.org/TR/xquery/)
- Xquery is a programming language
- is a functional language (
- used for XML documents and XML databases
- It uses XPATH
- useful for extraction and selection of XML fragments and construction of new elements
What is XQuery?
xquery version "3.1";
So, now, don't be confuse between Xquery and eXist.
It defines the version of Xquery we are using.
What is XQuery?
XQuery defines the FLWOR iteration syntax.
FLWOR is the acronym for for, let, where, order by, and return.
A FLWOR statement is made up of the following parts:
What is XQuery?
A FLWOR statement is made up of the following parts:
What is XQuery?
-
One or more FOR clauses that bind one or more iterator variables to input sequences.
-
An optional where clause. This clause applies a filter predicate on the iteration.
-
An optional order by clause.
-
An optional let clause. This clause assigns a value to the given variable for a specific iteration. The assigned expression can be an XQuery expression such as an XPath expression, and can return either a sequence of nodes or a sequence of atomic values.
-
A return expression. The expression in the return clause constructs the result of the FLWOR statement.
A FLWOR statement is made up of the following parts:
What is XQuery?
-
where: filter a sequence (optional) → never use with eXist-db!
Namespace (!)
declare namespace tei=”http://www.tei-c.org/ns/1.0";
XQUERY
Let's decrypt this script
doc > is a native function for Xquery, passing it the name of the resource to open --> ("../data/lettera_2.xml")
Within eXist-db will open resources known by eXist
let $titles := doc("../data/lettera_2.xml")//tei:title
return count($titles)
let $titles := doc("../data/lettera_2.xml")//tei:author
return count($titles)
LET > is used to set the value a variable through :=
What is a variable?
a variable is bound to a particular value. That value may be any sequence, including a single node or multiple nodes. They are precedeending by a dollar
XQUERY
let $titles := doc("../data/lettera_2.xml")//tei:title
return count($titles)
l
every time a let is set, you need than a return (!)
let $titles := doc("../data/lettera_2.xml")//tei:title
return count($titles)
Execute the count function giving the variable called $titles
XQUERY
XQUERY
for $title in doc("../data/lettera_2.xml")//tei:title
return $title
Title Text
XQUERY
xquery version "3.0";
declare namespace tei="http://www.tei-c.org/ns/1.0";
for $title in doc("../data/lettera_2.xml")//tei:title
return <p>{$title/data()}</p>
Title Text
XQUERY
xquery version "3.0";
declare namespace tei="http://www.tei-c.org/ns/1.0";
for $title in doc("../data/lettera_2.xml")//tei:title
order by string-length($title/data())
return <p>{$title/data()}</p>
Title Text
XQUERY
for $title in doc("../data/lettera_2.xml")//tei:title
where contains($title, ' ')
order by string-length($title/data())
return <p>{$title/data()}</p>
e/data()}</i>
XQUERY
xquery version "3.1"; declare namespace tei="
http://www.tei-c.org/ns/1.0";
for $title in doc("../data/lettera_2.xml")//tei:title
return if ($title/../name() = "titleStmt")
then <strong>{$title/data()}</strong>
else <i>{$title}</i>
Title Text
XQUERY
xquery version "3.1";
declare namespace tei="http://www.tei-c.org/ns/1.0";
for $title in doc("../data/lettera_2.xml")//tei:title
return if ($title/ancestor::tei:titleStmt)
then <p>{$title/data()}</p>
else <p>{$title/data()}</p>
Functions
Built-in Versus User-Definend Functions
- Function within Xquery
- You can create function with Xquery
- Functions belonging to eXide
XQUERY
Built-in Versus User-Definend Functions
Function within Xquery
All the Xpath functions can be used in Xquery as well
XQUERY
Built-in Versus User-Definend Functions
Function within Xquery
such as -- concat
xquery version "3.1";
declare namespace tei="http://www.tei-c.org/ns/1.0";
let $title := doc("../data/lettera_2.xml")//tei:titleStmt
return concat($title/tei:author, " ", $title/tei:title[1])
XQUERY
FunctionS
declare function prefix:function_name($parameter as datatype) as returnDatatype
{
...function code here...
};
prefix:function_name
you should add = module namespace app="http://exist-db.org/apps/myapp/templates";
Function
declare function local:getTitle {
}
XQUERY
Function
Built-in Versus User-Definend Functions
Definition: A module declaration serves to identify a module as a library module. A module declaration begins with the keyword module and contains a namespace prefix and a URILiteral.]
The URILiteral identifies the target namespace of the library module, which is the namespace for all variables and functions exported by the library module.
A MODULE CAN ONLY BE "DECLARE"
prefix:function_name
you should add = module namespace app="http://exist-db.org/apps/myapp/templates";
XQUERY
Return datatype
declare function local:getTitle () as xs:string
www.w3.org/2001/XMLSchema
L'XML-SCHEMA of the many things it does, define typologies of data.
XQUERY
Return datatype
declare function local:getTitle () as xs:integer {
42
};
declare function local:getTitle () as xs:string {
42
};
https://www.w3.org/TR/xmlschema-2/
XQUERY
Return datatype
declare function local:getTitle () as xs:integer {
string-join(doc("../data/lettera_2.xml")//tei:titleStmt/tei:title, "-")
};
XQUERY
$parameter as datatype
declare function local:getTitle($resource as xs:string) as xs:string {
string-join(doc($resource)//tei:titleStmt/tei:title, "-")
};
let $title := local:getTitle("../data/lettera_2.xml")
return $title
XQUERY
$parameter as datatype
let $title := local:getTitle("../data/lettera_2.xml")
let $title2 := local:getTitle("../data/lettera_3.xml")
return <p>{$title, $title2}</p>
L'XML nelle tante cose che fa, definisce anche i tipi di dato.
https://www.w3.org/TR/xmlschema-2/
XQUERY
Function
Built-in Versus User-Definend Functions
- Use the declare function keyword
- The name of the function must be prefixed
- The data type of the parameters are mostly the same as the data types defined in XML Schema
- The body of the function must be surrounded by curly braces
XQUERY
import a module
declare function app:getTitle($resource as xs:string) as xs:string {
string-join(doc($resource)//tei:titleStmt/tei:title, "-")
};
let $title := app:getTitle("../data/lettera_2.xml")
return $title
xquery version "3.1";
declare namespace tei="http://www.tei-c.org/ns/1.0";
import module namespace app="http://exist-db.org/apps/myapp/templates" at "app.xql";
let $title := app:getTitle("../data/lettera_2.xml")
return $title
XQUERY
Functions in the template always have two parameters
the first is ($node as node(),
node is the XML element with data-template attribute which trigger the execution of the function
and the second $model as map(*))
XQUERY
Functions in the template always have two parameters
the first is ($node as node(),
node is the XML element with data-template attribute which trigger the execution of the function
and the second $model as map(*))
XQUERY
declare function app:title($node as node(), $model as map(*)) {
<h1>{string-join(doc("../data/lettera_2.xml")//tei:titleStmt/tei:title, "-")}</h1>
};
XQUERY
declare function app:title($node as node(), $model as map(*)) {
<h1>{string-join(doc("../data/lettera_2.xml")//tei:titleStmt/tei:title, "-")}</h1>
};
XQUERY
Body
declare function app:body($node as node(), $model as map(*)) {
<p>{doc("../data/lettera_2.xml")//tei:body }</p>
};
XQUERY
---> index.html
<div data-template="app:body" />
XQUERY
---> index.html
Why is not imported the module?
XQUERY
Because it is processed in the template system. The template system runs because we have view.xql- (which is not a module)
view.xql >> import app.xlq
To create an element
declare function app:body($node as node(), $model as map(*)) {
element p {
doc("../data/lettera_2.xml")//tei:body
}
};
XQUERY
Body
declare function app:body($node as node(), $model as map(*)) {
element p {
attribute style { "border: 1px solid red" },
doc("../data/lettera_2.xml")//tei:body
}
};
XQUERY
Body
declare function app:body($node as node(), $model as map(*)) {
let $id := request:get-parameter("id", ())
let $object := collection("apps/example/data")/tei:TEI[@xml:id = $id]
return
element p {
$object//tei:body
}
};
XQUERY
eXist-db Functions
request:get-parameter
XQUERY - eXist-db
Text
More on eXist-db
- The dashboard
- Tei-Publisher
- Application management with package-manager
- Monitoring
- Backup & restore
- Integrates very nicely with oXygen
- Comments (: this is a comment! :)
declare function app:title($node as node(), $model as map(*)) {
let $id := request:get-parameter("id", ())
let $object := collection("apps/example/data")/tei:TEI[@xml:id = $id]
return
element h1 {
string-join($object//tei:titleStmt/tei:title, "-")
}
};
declare function app:body($node as node(), $model as map(*)) {
let $id := request:get-parameter("id", ())
let $object := collection("apps/example/data")/tei:TEI[@xml:id = $id]
return
element p {
$object//tei:body
}
};
declare function app:letterList($node as node(), $module as map(*)) {
element ul {
for $object in collection("apps/example/data")/tei:TEI
return
element li {
element a {
attribute href { concat("letter.html?id=", $object/@xml:id) },
$object//tei:title/data(.)
}
}
}
};
Xquery - eXist-db
By Tiziana Mancinelli
Xquery - eXist-db
A workshop at the EDEEN - Digital Humanities Summer School at University of Grenoble
- 771