1. Constructors

    Constructors 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
    1. Direct Constructors

      Direct constructors use XML notation to create XML structures.

      1. Direct Element Constructors

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

        <employee>
         {
           /people/person/name
         }
        </employee>
        result:
        <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)

        <employees>
         {
           for $i in /people/person
           return <employee>
           {
             data($i/name)
           }
           </employee>
         }
        </employees>
        result:
        <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.
      2. Direct Attribute Constructors

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

        <employees>
         {
           for $i in /people/person
           return <employee department="{$i/@dept}">
           {
             data($i/name)
           }
           </employee>
         }
        </employees>
        result:
        <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}"
      3. Direct Namespace Constructor

        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>
        result:
        <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'.
      4. Direct Comment Constructor

        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-->
        result:
        <!-- 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>
        result:
        <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.
      5. Direct Processing Instruction Constructor

        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"?>
        result:
        <?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

        let $pi := <?xml-stylesheet type="text/xsl" href="people.xslt"?>
        let $x := /*
        return document  {($pi , $x)}
        result:
        <?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).
    2. Computed Constructors

      Unlike direct constructors which use XML notation, computed constructors use a non XML notation to create XML structures in XQuery expressions.

      1. Computed Element Constructors

        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

        <employees>
          {
            for $i in /people/person
            return element employee {data($i/name)}
          }
        </employees>
        result:
        <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

        <people>
          {
            for $i in /people/person
            return element {$i/name} {data($i/age)}
          }
        </people>
        result:
        <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)}
      2. Computed Attribute Constructors

        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

        <people>
          {
            attribute total { count(/people/person) },
            for $i in /people/person return $i
          }
        </people>
        result:
        <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

        let $p :=  concat('number_of_' , name(/*))
        return <people>
                 {
                   attribute { $p } { count(/people/person) },
                   for $i in /people/person
                   return $i
                 }
               </people>
        result:
        <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) }
      3. Computed Namespace Constructors

        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>
        result:
        <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'}.
      4. Computed Text Constructors

        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

        <div>
          {
            for $i in /people/person
            return element p { text { concat ($i/name,  ' is ' , $i/age)  }  }
          }
        </div>
        result:
        <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.
      5. Document Constructors

        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

        let $pi := <?xml-stylesheet type="text/xsl" href="people.xslt"?>
        let $x := /*
        return document  { ($pi , $x) }
        result:
        <?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).
      6. Computed Comment Constructors

        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

        <people>
         {
             for $i in /people/person
             count $x
             return ( comment { concat( "comment describing person # " , $x  ) }, $i )
           }
        </people>
        result:
        <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.
      7. Computed Processing Instruction Constructors

        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

        let $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)}
        result:
        <?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.
    3. Enclosed Expressions

      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.

      1. Enclosed Expressions and Direct 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

        <root>/people/person</root> 
        result:
        <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.

        <root>{/people/person}</root>
        result:
        <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.

        <root total="count(/people/person)"></root>
        result:
        <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

        <root total="{count(/people/person)}"></root>
        result:
        <root total="4"/>
        The function call count(/people/person) is evaluated because it is contained within { and }.
      2. Enclosed Expressions and Computed Constructors

        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

        for $i in /people/person
        return element { concat( $i/name , '_from_' , $i/@dept  ) } { data( $i/age ) }
        result:
        <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

        let $ages :=  string-join( /people/person/age ,  ', ' )
        return text { concat ( 'The age of all employees: ' , $ages  ) }
        result:
        '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.