# XQuery 3 Training

PreviousHomeNextConstructors are used to **construct XML structures** in XQuery expressions.

Constructors are available to construct the following nodes: 

- **element**
- **attribute**
- **document**
- **text**
- **comment**
- **processing instruction**

There are two kinds of constructor: 

- **direct constructors**
- **computed constructors**

Direct constructors use **XML notation** to **create XML structures**.

**Direct element constructors** are used to **create element nodes**.

Direct element constructors: 

- create **elements** using **XML notation**
- use **constants** to **specify element names**
- **cannot** be used to **compute element names**
- use **constants** OR **enclosed expressions** for **element content**

example: Direct element constructor with constant for element content

<employee>jennifer</employee><employee>jennifer</employee>The **direct element constructor** in this example constructs an element named **employee** with a value of **'jennifer'**.

example: Direct element constructor with enclosed expression for element content

/images/training/xquery/people.png<employee>
 {
   /people/person/name
 }
</employee><employee>
  <name>mary</name>
  <name>cindy</name>
  <name>john</name>
  <name>peter</name>
</employee>

- This XQuery example consists of a **direct element constructor** and an **enclosed expression**.
- The **direct element constructor** creates an element named **employee**.
- The **enclosed expression** provides the content for the **employee** element by retrieving the **name** child element nodes of **person**.

example: Direct element constructor with enclosed expression (which also contains a direct element constructor with enclosed expression)

/images/training/xquery/people.png<employees>
 {
   for $i in /people/person
   return <employee>
   {
     data($i/name)
   }
   </employee>
 }
</employees><employees>
  <employee>mary</employee>
  <employee>cindy</employee>
  <employee>john</employee>
  <employee>peter</employee>
</employees>

- This more complex XQuery example uses two **direct element constructors**, one for **employees** and one for **employee**.
- Each **direct element constructor** also contains an **enclosed expression** for the element content.

**Direct attribute constructors** are used to **create attribute nodes**.

Direct attribute constructors: 

- create **attributes** using **XML notation**
- appear in the **start tag** of a **direct element constructor**
- use **constants** to **specify attribute names**
- **cannot** be used to **compute attribute names**
- use **constants** or **enclosed expressions** for **attribute values**

example: Direct attribute constructor with constant for attribute value

<employee department='human resources'>jennifer</employee><employee department='human resources'>jennifer</employee>The **direct element constructor** in this example constructs an element named **employee** with a value of **'jennifer'**. The **direct attribute constructor** creates an attribute named **department** with a value of **'human resources'**.

example: Direct attribute constructor with enclosed expression for attribute value

/images/training/xquery/people.png<employees>
 {
   for $i in /people/person
   return <employee department="{$i/@dept}">
   {
     data($i/name)
   }
   </employee>
 }
</employees><employees>
  <employee department="sales">mary</employee>
  <employee department="marketing">cindy</employee>
  <employee department="sales">john</employee>
  <employee department="accounting">peter</employee>
</employees>

- This XQuery example consists of two **direct element constructors**, a **direct attribute constructor** and three **enclosed expressions**.
- The **direct element constructors** create the elements **employees** and **employee**.
- The **direct attribute constructor** creates an attribute **department**.
- An **enclosed expression** is used to compute the **value** of the **department** attribute i.e. **department="{$i/@dept}** "

**Direct namespace constructors** are used inside **direct element constructors** to **bind a namespace prefix or set the default namespace for the constructed element node and its attributes**.

Direct namespace constructors 

- create **namespace declarations** using **XML notation**
- appear inside **direct element constructors**.
- use **constants** to **specify namespace declarations**.

example: Direct namespace constructor for default namespace declaration

<abc:people xmlns:abc="http://my-company"></people><abc:people xmlns:abc="http://my-company"></people>

- The **direct element constructor** in this example constructs an element named **people**.
- The **direct namespace constructor** creates a prefixed namespace declaration for the **http://my-company** namespace i.e. **xmlns:abc='http://my-company'**.

**Direct comment constructors** are used to create **comment nodes** in XQuery expressions. 

Direct comment constructors 

- create **comments** using **XML notation**

example: Direct comment constructor

<!-- this is a comment--><!-- this is a comment-->The **direct comment constructor** in this example creates a comment i.e. **<!-- this is a comment-->**

example: Direct comment constructor inside a direct element constructor

<people><!-- this is a comment--></people><people><!-- this is a comment--></people>

- The **direct element constructor** in this example creates an element named **people**.
- The **direct comment constructor** inside the element constructor creates a comment i.e. **<!-- this is a comment-->** inside the element.

**Direct processing instruction constructors** are used to create **processing instruction nodes** in XQuery expressions.

Direct processing instruction constructors 

- create **processing instructions** using **XML notation**

example: Direct processing instruction constructor

<?xml-stylesheet type="text/xsl" href="people.xslt"?><?xml-stylesheet type="text/xsl" href="people.xslt"?>The **direct processing instruction constructor** in this example constructs the processing instruction node **<?xml-stylesheet type="text/xsl" href="people.xslt"?>**.

example: Direct processing instruction constructor appearing before root element of computed document node

/images/training/xquery/people.pnglet $pi := <?xml-stylesheet type="text/xsl" href="people.xslt"?>
let $x := /*
return document  {($pi , $x)}<?xml-stylesheet type="text/xsl" href="people.xslt"?>
<people>
  <person dept="sales">
    <name>mary</name>
    <age>20</age>
  </person>
  <person dept="marketing">
    <name>cindy</name>
    <age>25</age>
  </person>
  <person dept="sales">
    <name>john</name>
    <age>40</age>
  </person>
  <person dept="accounting">
    <name>peter</name>
    <age>35</age>
  </person>
</people>

- The first **let** clause in this XQuery example binds the processing instruction **<?xml-stylesheet type="text/xsl" href="people.xslt"?>** created using a **direct processing instruction constructor** to the variable **$pi**.
- The second **let** clause binds the source xml file's root element and its contents to the variable **$x**.
- The **return** clause uses a **computed document constructor** to create a **document node**. The contents of the document node are computed in an enclosed expression by evaluating the sequence **($pi, $x)**.

Unlike direct constructors which use XML notation, **computed constructors** use a **non XML notation** to **create XML structures** in XQuery expressions.

**Computed element constructors** use a **non XML notation** to **create element nodes** in XQuery expressions.

Computed element constructors: 

- create **elements** using a **non XML notation**.
- can use **constants** to **specify element names**.
- can use **enclosed expressions** to **compute element names**.
- use **enclosed expressions** to **compute element content**.

A **computed element constructor** begins with the keyword **element** followed by the **name** of the element.

The **name** of the element can be **specified** as a **constant** OR be **computed** using an **enclosed expression**.

The **constant** or **enclosed expression** used for the **element name** is followed by an **enclosed expression** to **compute** the **element content**.

example: Computed element constructor with constant for element name and enclosed expression for element content

/images/training/xquery/people.png<employees>
  {
    for $i in /people/person
    return element employee {data($i/name)}
  }
</employees><employees>
  <employee>mary</employee>
  <employee>cindy</employee>
  <employee>john</employee>
  <employee>peter</employee>
</employees>

- This XQuery example begins with a **direct element constructor** for **employees** and an **enclosed expression** for the contents of **employees**.
- The **enclosed expression** contains a **for** clause which binds the variable **$i** to the sequence of **/people/person** nodes.
- The **return** clause uses a **computed element constructor** to construct an element.
- The **computed element constructor** uses a **constant** to specify the **element name** i.e. **employee**.
- The **computed element constructor** uses an **enclosed expression** to compute the **element content** i.e. **{data($i/name)}**

example: Computed element constructor with enclosed expression for element name and enclosed expression for element content

/images/training/xquery/people.png<people>
  {
    for $i in /people/person
    return element {$i/name} {data($i/age)}
  }
</people><people>
  <mary>20</mary>
  <cindy>25</cindy>
  <john>40</john>
  <peter>35</peter>
</people>

- This XQuery example begins with a **direct element constructor** for **people** and an **enclosed expression** for the contents of **people**.
- The **enclosed expression** contains a **for** clause which binds the variable **$i** to the sequence of **/people/person** nodes.
- The **return** clause uses a **computed element constructor** to construct an element.
- The **computed element constructor** uses a first **enclosed expression** to compute the **element name** i.e. **{$i/name}**
- The **computed element constructor** uses a second **enclosed expression** to compute the **element content** i.e. **{data($i/age)}**

**Computed attribute constructors** use a **non XML notation** to **create attribute nodes** in XQuery expressions.

Computed attribute constructors: 

- create **attributes** using a **non XML notation**.
- **can** use **constants** to **specify attribute names**.
- **can** use **enclosed expressions** to **compute attribute names**.
- use **enclosed expressions** to **compute attribute values**.

A **computed attribute constructor** begins with the keyword **attribute** followed by the **name** of the attribute.

The **name** of the attribute can be **specified** as a **constant** OR be **computed** using an **enclosed expression**.

The **constant** or **enclosed expression** used for the **attribute name** is followed by an **enclosed expression** to **compute** the **attribute value**.

example: Computed attribute constructor with constant for attribute name and enclosed expression for attribute value

/images/training/xquery/people.png<people>
  {
    attribute total { count(/people/person) },
    for $i in /people/person return $i
  }
</people><people total="4">
  <person dept="sales">
    <name>mary</name>
    <age>20</age>
  </person>
  <person dept="marketing">
    <name>cindy</name>
    <age>25</age>
  </person>
  <person dept="sales">
    <name>john</name>
    <age>40</age>
  </person>
  <person dept="accounting">
    <name>peter</name>
    <age>35</age>
  </person>
</people>

- This XQuery example consists of a **direct element constructor** for **people** and an **enclosed expression** for the **element content**.
- The **enclosed expression** in the **direct element constructor** contains a **computed attribute constructor**.
- The **computed attribute constructor** uses a **constant** to specify the **attribute name** i.e. **total**.
- The **computed attribute constructor** uses an **enclosed expression** to compute the **attribute value** i.e. **{count(/people/person)}**

example: Computed attribute constructor with enclosed expressions for attribute name and attribute value

/images/training/xquery/people.pnglet $p :=  concat('number_of_' , name(/*))
return <people>
         {
           attribute { $p } { count(/people/person) },
           for $i in /people/person
           return $i
         }
       </people><people number_of_people="4">
  <person dept="sales">
    <name>mary</name>
    <age>20</age>
  </person>
  <person dept="marketing">
    <name>cindy</name>
    <age>25</age>
  </person>
  <person dept="sales">
    <name>john</name>
    <age>40</age>
  </person>
  <person dept="accounting">
    <name>peter</name>
    <age>35</age>
  </person>
</people>

- This XQuery example begins with a **let** clause which binds the variable **$p** to the string **'number_of_people'** (which is the result of concatenating **'number_of_'** with the name of the source xml document's root element **people**).
- The **return** clause uses a **direct element constructor** to create an element named **people**.
- The **enclosed expression** in the **direct element constructor** contains a **computed attribute constructor**.
- The **computed attribute constructor** uses a first **enclosed expression** to compute the **attribute name** i.e. **{ $p }**
- The **computed attribute constructor** uses a second **enclosed expression** to compute the **attribute value** i.e. **{ count(/people/person) }**

**Computed namespace constructors** use a **non XML notation** to **create namespace nodes** in XQuery expressions.

Computed namespace constructors: 

- create **namespace nodes** using a **non XML notation**.
- **can** use **constants** to **specify namespace prefixes**.
- **can** use **enclosed expressions** to **compute namespace prefixes**.
- use **enclosed expressions** to **compute namespaces**.

A **computed namespace constructor** begins with the keyword **namespace** followed by a **constant** or **enclosed expression** to **specify** or **compute** the **namespace prefix**.

The **constant** or **enclosed expression** used for the **namespace prefix** is followed by an **enclosed expression** to **compute** the **namespace**.

example: Computed namespace constructor with constant for namespace prefix

<people>
 {
  namespace xsi {'http://www.w3.org/2001/XMLSchema-instance'},
  attribute xsi:noNamespaceSchemaLocation {'people.xsd'}, element {'person'} {}
 }
</people><people xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="people.xsd">
	<person/>
</people>

- This XQuery example begins with a **direct element constructor** for **people**.
- The **direct element constructor** for **people** contains an **enclosed expression**.
- The **enclosed expression** contains a **computed namespace constructor** followed by a **computed attribute constructor** and a **computed element constructor**.
- The **computed namespace constructor** uses a **constant** i.e. **xsi** to specify the **namespace prefix**.
- The **computed namespace constructor** uses an **enclosed expression** to compute the **namespace** i.e. **{'http://www.w3.org/2001/XMLSchema-instance'}**.

**Computed text constructors** use a **non XML notation** to **create text nodes** in XQuery expressions.

Computed text constructors: 

- create **text nodes** using a **non XML notation**.
- use **enclosed expressions** to **compute** the **text node content**.

A **computed text node constructor** begins with the keyword **text** followed by an **enclosed expression** to **compute** the **text node content**.

example: Computed text constructor with enclosed expression to compute text node content

/images/training/xquery/people.png<div>
  {
    for $i in /people/person
    return element p { text { concat ($i/name,  ' is ' , $i/age)  }  }
  }
</div><div>
  <p>mary is 20</p>
  <p>cindy is 25</p>
  <p>john is 40</p>
  <p>peter is 35</p>
</div>

- This example begins with a **direct element constructor** for **div**.
- The **content** of **div** is computed by an **enclosed expression**.
- The **for** clause in the **enclosed expression** binds the variable **$i** to the **/people/person** nodes.
- The **return** clause uses a **computed element constructor** to create an element **p**.
- The **computed element constructor** for **p** contains an **enclosed expression** to compute the **element content**.
- The **enclosed expression** contains a **computed text constructor** which creates a **text node**.
- The **computed text constructor** contains an **enclosed expression** for the **text content**.
- The **enclosed expression** creates the **text content** by concatenating **$i/name**, the string **' is '** and **$i/age**.

**Document constructors** use a **non XML notation** to **create document nodes** (highest level of the XML DOM node hierarchy) in XQuery expressions.

Document constructors: 

- create **document nodes** using a **non XML notation**.
- use **enclosed expressions** to **compute** the **document node content**.

A **document constructor** begins with the keyword **document** followed by an **enclosed expression** to **compute** the **document content**.

example: Document constructor which creates a document from a sequence of nodes

/images/training/xquery/people.pnglet $pi := <?xml-stylesheet type="text/xsl" href="people.xslt"?>
let $x := /*
return document  { ($pi , $x) }<?xml-stylesheet type="text/xsl" href="people.xslt"?>
<people>
  <person dept="sales">
    <name>mary</name>
    <age>20</age>
  </person>
  <person dept="marketing">
    <name>cindy</name>
    <age>25</age>
  </person>
  <person dept="sales">
    <name>john</name>
    <age>40</age>
  </person>
  <person dept="accounting">
    <name>peter</name>
    <age>35</age>
  </person>
</people>

- The first **let** clause in this XQuery example binds the processing instruction **<?xml-stylesheet type="text/xsl" href="people.xslt"?>** created using a **direct processing instruction constructor** to the variable **$pi**.
- The second **let** clause binds the source xml file's root element and its contents i.e. /* to the variable **$x**.
- The **return** clause uses a **document constructor** to create a **document node**.
- The **contents** of the **document node** are **computed** in an **enclosed expression** by evaluating the sequence **($pi, $x)**.

**Computed comment constructors** use a **non XML notation** to **create comment nodes** in XQuery expressions.

Computed comment constructors: 

- create **comment nodes** using a **non XML notation**.
- use **enclosed expressions** to **compute** the **comment node content**.

A **computed comment constructor** begins with the keyword **comment** followed by an **enclosed expression** to **compute** the **comment content**.

example: Computed comment constructor with enclosed expression to compute content of comment node

/images/training/xquery/people.png<people>
 {
     for $i in /people/person
     count $x
     return ( comment { concat( "comment describing person # " , $x  ) }, $i )
   }
</people><people>
  <!--comment describing person # 1-->
  <person dept="sales">
    <name>mary</name>
    <age>20</age>
  </person>
  <!--comment describing person # 2-->
  <person dept="marketing">
    <name>cindy</name>
    <age>25</age>
  </person>
  <!--comment describing person # 3-->
  <person dept="sales">
    <name>john</name>
    <age>40</age>
  </person>
  <!--comment describing person # 4-->
  <person dept="accounting">
    <name>peter</name>
    <age>35</age>
  </person>
</people>

- This example begins with a **direct element constructor** for **people** and an **enclosed expression** for the **content** of **people**.
- The **enclosed expression** contains a **for** clause which binds the variable **$i** to the **/people/person** nodes.
- The **for** clause is followed by a **count** clause which binds the variable **$x** to the ordinal position of each tuple in the input stream.
- The **return** clause returns a sequence of items: a **comment** created using a **computed comment constructor** followed by **$i** i.e. the respective **person** node and its **content**.
- The **computed comment constructor** constructs the **content** of each **comment** by concatenating the string **'comment describing person # '** with the respective counter i.e. **$x**.

**Computed processing instruction constructors** use a **non XML notation** to **create processing instruction nodes** in XQuery expressions.

Computed processing instructions: 

- create **processing instructions** using a **non XML notation**.
- can use **constants** to **specify** the **target** property of the **processing instruction**.
- can use **enclosed expressions** to **compute** the **target** property of the **processing instruction**.
- use **enclosed expressions** to **compute** the **content** of the **processing instruction**.

A **computed processing instruction** begins with the keyword **processing-instruction** followed by a **constant** or an **enclosed expression** for the processing instruction's **target** property. 

The **constant** or **enclosed expression** used for the **target** property is followed by an **enclosed expression** to **compute** the **content** of the **processing instruction**.

example: computed processing instruction node with enclosed expressions for target and content

/images/training/xquery/people.pnglet $target := 'xml-stylesheet'
let $type := 'type="text/xsl"'
let $file := concat(name(/*), '.xslt')
let $href := concat('href="',  $file, '"')
let $content  := ($type , $href)
let $pi := processing-instruction {$target }{$content }
let $x := /*
return document  {($pi , $x)}<?xml-stylesheet type="text/xsl" href="people.xslt"?>
<people>
  <person dept="sales">
    <name>mary</name>
    <age>20</age>
  </person>
  <person dept="marketing">
    <name>cindy</name>
    <age>25</age>
  </person>
  <person dept="sales">
    <name>john</name>
    <age>40</age>
  </person>
  <person dept="accounting">
    <name>peter</name>
    <age>35</age>
  </person>
</people>

- This example uses several **let** clauses to bind values to variables.
- The variable **$target** is bound to the string **'xml-stylesheet'**.
- The variable **$content** evaluates to **'type="text/xsl" href="people.xslt"'**.
- The variable **$pi** is bound to a **computed processing instruction constructor** which uses an **enclosed expression** to **compute** the **target** of the processing instruction i.e. **{$target}** and an **enclosed expression** to **compute** the **processing instruction content** i.e. **{$content}**.
- The **return** clause uses a **document constructor** which uses an **enclosed expression** to compute the document's content.
- The **enclosed expression** used to **compute** the **document content** returns a sequence of the processing instruction evaluated to by **$pi** followed by all of the elements in the source document **$x**.

In XQuery **enclosed expressions** are expressions contained within **{** and **}**.

Enclosed expressions are used in three ways: 

- With **direct constructors** they are used to indicate to the processor that the expression should be **evaluated** as opposed to being output as literal text.
- With **computed constructors** they are used to **specify certain properties** of the node being constructed
- With **user defined functions** the are used to encapsulate the **function body**

The following sections will show how enclosed expressions are used with direct and computed constructors.

When using **direct constructors** it is important to enclose those parts of the XQuery expression which need to be **evaluated** with **{** and **}** to prevent them from being output as literal text.

example: XPath statement in XQuery expression output as literal text

/images/training/xquery/people.png<root>/people/person</root> <root>/people/person</root> The XPath statement **/people/person** in this example **is not** evaluated because it **is not** contained within **{** and **}** and is therefore output as **literal text**.

example: XPath statement contained within enclosed expression in XQuery expression is evaluated.

/images/training/xquery/people.png<root>{/people/person}</root><root>
  <person dept="sales">
    <name>mary</name>
    <age>20</age>
  </person>
  <person dept="marketing">
    <name>cindy</name>
    <age>25</age>
  </person>
  <person dept="sales">
    <name>john</name>
    <age>40</age>
  </person>
  <person dept="accounting">
    <name>peter</name>
    <age>35</age>
  </person>
</root>The XPath statement **/people/person** is evaluated because it **is** contained within **{** and **}**.

example: Function call to compute attribute value in XQuery expression is output as literal text.

/images/training/xquery/people.png<root total="count(/people/person)"></root><root total="count(/people/person)"></root>The function call **count(/people/person)****is not** evaluated because it **is not** contained within **{** and **}** and is therefore output as literal text.

example: Function call to compute attribute value in XQuery expression is evaluated

/images/training/xquery/people.png<root total="{count(/people/person)}"></root><root total="4"/>The function call **count(/people/person) is** evaluated because it **is** contained within **{** and **}**.

Depending on the type of **computed constructor**, multiple enclosed expressions may be used to specify properties of the node being constructed.

example: Enclosed expressions in a computed element constructor used to compute element name and value

/images/training/xquery/people.pngfor $i in /people/person
return element { concat( $i/name , '_from_' , $i/@dept  ) } { data( $i/age ) }<mary_from_sales>20</mary_from_sales>
<cindy_from_marketing>25</cindy_from_marketing>
<john_from_sales>40</john_from_sales>
<peter_from_accounting>35</peter_from_accounting>The **computed element constructor** in this example uses two enclosed expressions. The first enclosed expression **{ concat ( $i/name , '_from_' , $i/@dept ) }** is used to compute the **element name**. The second enclosed expression **{ data($i/age) }** is used to compute the **element content**.

example: Enclosed expression in a text constructor used to compute text value

/images/training/xquery/people.pnglet $ages :=  string-join( /people/person/age ,  ', ' )
return text { concat ( 'The age of all employees: ' , $ages  ) }'The age of all employees: 20, 25, 40, 35'The **computed text constructor** in this example uses an enclosed expression **text{ concat ( 'The age of all employees are: ' , $ages ) }** to compute the **text value**. Text nodes do not have a **name** so only one enclosed expression is used by a computed text node constructor.

PreviousHomeNext