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 :=

Xquery

 

 

 

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.

 

https://www.w3.org/TR/xmlschema-2/

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

  • 689