XQUERY

Tiziana Mancinelli

 

 

XQUERY

Learn XQuery: A list of great articles, blog posts, and books for learning XQuery

https://github.com/joewiz/learn-xquery

Resources

  • 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?

 

Tools to use Xquery

 

- Databases - BaseX - ExistDB

- Xquilla (riga di comando)

- A few libraries to embed Xquery

- oXygen

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!

Let's remember the

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/example.xml")

 

Within eXist-db will open resources known by eXist

 

xquery version "3.1";
declare namespace tei="http://www.tei-c.org/ns/1.0"; 

let $titles := doc("../data/esempio.xml")//tei:title
return $titles

 

 

 

 

LET > is used to set the value  a variable through :=

Xquery



let $titles := doc("../example.xml")//tei:author
return count($titles)

 

 

 

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/example.xml")//tei:title
      return count($titles)

l

 

 every time a let is set, you need than a return (!)

 

 

let $titles := doc("../data/example.xml")//tei:title
      return count($titles)

Execute the count function giving the variable called $titles

XQUERY

XQUERY

for $title in doc("../data/example.xml")//tei:title

return $title

Let's have another example with 'for'

XQUERY

In order to return the content of a node, use:

 




let $namevariable := doc(example.xml)/elementXML
return $navariable/data()

XQUERY

Building New HTML or XML with XQuery: Using Curly Braces: { }

 

To add HTML or XML markup to the XQuery output, add the elements where needed to produce conformant code. However, these elements are passive, or non-functional when executing XQuery commands. So we use curly-braces { } to enclose any XPath or XQuery statements that we want to execute in XQuery, to separate them from the HTML or XML markup elements. Inside html elements, when we need to do some calculation or refer to a variable we defined in XQuery, we use the curly-braces again.

Title Text

XQUERY

xquery version "3.0";

declare namespace tei="http://www.tei-c.org/ns/1.0";

for $title in doc("../data/example.xml")//tei:title
return <p>{$title/data()}</p>

An example with order by

XQUERY

xquery version "3.0";

declare namespace tei="http://www.tei-c.org/ns/1.0";

for $title in doc("../data/example.xml")//tei:title
    order by string-length($title/data())
    return <p>{$title/data()}</p>

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>

An example with where

e/data()}</i>

XQUERY

xquery version "3.1"; 

declare namespace tei="http://www.tei-c.org/ns/1.0"; 

for $title in doc("example.xml")//tei:title

    return if ($title/../name() = "titleStmt")

           then <strong>{$title/data()}</strong>

           else <i>{$title/data()}</i>

Let's have a condition! (: let's have fun! :)

Title Text

XQUERY

xquery version "3.1";

declare namespace tei="http://www.tei-c.org/ns/1.0";

for $title in doc("example.xml")//tei:title

    return if ($title/ancestor::tei:titleStmt) place="marginleft"
    
        then <strong>{$add/data()}</strong>

        else <em>{$title/data()}</em>

Functions

 

Built-in Versus User-Definend Functions

  • Function within Xquery
  • You can create function with Xquery

 

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:respStmt/tei:name/data(), ", ", " ",  $title/tei:title)

XQUERY

(: Functions :)

 

 

 

 

 


 

 

 

 

declare function prefix:function_name($parameter as datatype) as returnDatatype
                            {
                                 ...function code here...
                             };

Parameters needs to be followed by a comma!

Function

 

 

 


 

 

 

declare namespace tei="http://www.tei-c.org/ns/1.0"; 

declare function local:countHands($node as node()) {
    count($node//*[@hand])
};

let $root := doc("Frankenstein-v1c5-transcription.xml")

return <html>
             <body>
                <p>Corrections: {local:countHands($root)}</p>
             </body>
       </html>

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:string {
    string-join(doc("example.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

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

 

 

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

let $root := doc("Frankenstein-v1c5-transcription.xml")

return <html>
            <head>
             <link
                rel="stylesheet"
                href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"/>
            <meta
                charset="UTF-8"/>
            </head>
             <body><div
                class="container">
                <div
                    class="row">
                    <div
                        class="col-sm">
                        {
                            let $graphicUrl := $root//tei:facsimile/tei:graphic/@url
                            return
                                <img
                                    width="600"
                                    src="{$graphicUrl}"/>
                        }
                    </div>
                    <div
                        
                        
                        Corrections: {local:countHands($root)}
                    </div>
                </div>
            </div>
             </body>
       </html>
declare function local:applyTemplates($nodes as node()*) as node()* {
    for $node in $nodes
    return
        typeswitch ($node)
            case element(tei:head)
                return
                    local:applyTemplateHead($node)
            case element(tei:p)
                 return local:applyTemplateP($node)
            case element()
                 return local:applyTemplates($node/node())
            default
                return $node
        }

Typeswitch

Typeswitch

The most effective way to use the typeswitch expression to transform XML is to create a series of XQuery functions. In this way, we can cleanly separate the major actions of the transformation into modular functions. (In fact, the library of functions can be saved into an XQuery library module, which can then be reused by other XQueries.) The "magic" of this typeswitch-style transformation is that once you understand the basic pattern and structure of the functions, you can adapt them to your own data. You'll find that the structure is so modular and straightforward that it's even possible to teach others the basics of the pattern in a short period of time and empower them to maintain and update the transformation rules themselves.

declare function local:applyTemplateHead($node as node()) as node()* {
    <h1>{local:applyTemplates($node/node())}</h1>
};

declare function local:applyTemplateP($node as node()) as node()* {
    <p>{local:applyTemplates($node/node())}</p>
};
<html>
            <head>
             <link
                rel="stylesheet"
                href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"/>
            <meta
                charset="UTF-8"/>
            </head>
             <body><div
                class="container">
                <div
                    class="row">
                    <div
                        class="col-sm">
                        {
                            let $graphicUrl := $root//tei:facsimile/tei:graphic/@url
                            return
                                <img
                                    width="600"
                                    src="{$graphicUrl}"/>
                        }
                    </div>
                    <div
                        class="col-sm"
                        style="margin-left: 5em">
                        {
                            let $teiHead := $root//tei:head
                            return local:applyTemplates($teiHead)
                        }
                        
                         {
                            let $teiP := $root//tei:div//tei:p
                            return local:applyTemplates($teiP)
                        }
                        
                        Corrections: {local:countHands($root)}
                    </div>
                </div>
            </div>
             </body>
       </html>
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

Xquery - Bologna2021

By Tiziana Mancinelli

Xquery - Bologna2021

University of Bologna - Xquery

  • 508