Previous Next Contents

Chapter 2    Examples

This chapter introduces X-OQL. It describes and illustrates basic queries, and shows how they can be used to build more elaborate ones.

In the following examples, we will consider two simple XML documents, products.xml and persons.xml. Their contents are given in Figures 2.1 and 2.2.

You can run these queries by starting the X-OQL console:
> java xoql.Console examples

<products> 
 <product reference="012458796">
  <type> tv-set</type> 
  <description> a great color tv set </description> 
  <price>200</price> 
  <sales> 
   <sale> 
    <vendor> mike </vendor> 
    <date> 12-24-1998 </date> 
   </sale> 
   <sale> 
    <vendor>john</vendor> 
    <date>12-20-1998</date> 
   </sale> 
  </sales> 
  </product> 
 <product reference="6987654"> 
  <description> video tape recorder </description> 
  <price>200</price> 
  <sale> 
   <vendor>mike</vendor> 
  </sale> 
 </product> 
</products>


Figure 2.1: The products.xml example document


<persons> 
 <manager id="fbogus"> 
  <first-name> fred </first-name> 
  <last-name> bogus </last-name> 
 </manager> 
 <vendors> 
  <vendor id="mike" manager="fbogus"> 
   <age> 24 </age> 
   <salary>5000</salary> 
   <commission> 3000 </commission> 
  </vendor> 
  <vendor id="john" manager="fbogus"> 
   <age/> 
   <salary> 10000 </salary> 
  </vendor> 
 </vendors> 
 <customers> 
  <customer> 
   <name> bart simpson </name> 
   <address> 10, down street </address> 
   <customs> 
    <custom> a tv set </custom> 
   </customs> 
  </customer> 
 </customers> 
</persons>


Figure 2.2: The persons.xml example document

X-OQL allows querying denotable objects starting from their names, wich act as entry points into a collection of XML documents. We will further call a datasource a dictionary in which some names have been defined in order to denote some DOM nodes. Figure 2.3 illustrates the use of a datasource to address the two example documents. The products document is supposed to be stored in a DOM compliant XML repository, whereas the persons document is represented as a in-memory DOM tree. The name vendors denotes the root node of the corresponding subtree of the persons document. Note that the name of the named object vendors is the same as the label of the corresponding node. This is an arbitrary choice, made for clarity and consistency reasons.


1datasource.eps

Figure 2.3: A datasource

2.1  Datasource entry points

The simplest X-OQL query simply consists of an entry point:
customers;
Since the datasource contains an entry point whose name is customers, the result is:
<result>
  <customers> 
    <customer> 
      <name> bart simpson </name> 
      <address> 10, down street </address> 
      <customs> 
        <custom> a tv set </custom> 
      </customs> 
    </customer> 
  </customers> 
</result>

2.2  Simple queries

2.3  Path Expressions

One can enter a document through a named object. It is then convenient to use a form of navigation based on path expressions. The idea is to specify paths in the DOM tree based on the sequence of labels on nodes. We describe here simple path expressions, which allow users to obtain the set of nodes reachable by following a sequence of labels starting from a named object. A more powerful form of path expressions based on regular expressions is described in the sequel.

2.3.1  Accessing subelements

To do this, we use the / operator, wich enables us to go inside complex documents. For instance, the query :
vendors/vendor/salary;
means: start from the named object vendors, go inside the vendor set of nodes to get and finally retrieve the salary subnodes. Its result is:
<result>  
  <salary>5000</salary > 
  <salary>10000</salary> 
</result>
Note that here we copied the data from the original document in order to build the result. We can do better by dealing with references into the original document. For instance, using XLink/XPointer notation, the resulting document would be:
<result>  
  <link xml:link = "persons.xml/child(2).(1).(2)">
  <link xml:link = "persons.xml/child(2).(2).(2)">
</result>
Such more complx results can be obtained using X-OQL as an embedded language into a Java program.

2.3.2  Accessing attributes

Attributes can be accessed using the @ operator. For instance:
vendors/vendor/@id
retrieves the id attributes of the vendor elements, starting from the named object vendors.

2.4  Select From Where construct

The basic syntax of X-OQL is based on OQL and illustrated with the following query:
select v
from v in vendors/vendor;
Informally, the semantic of the query is to bind the variable v to each node specified by the path expression.
<result>
  <vendor 
    id="mike" 
    manager="fbogus"> 
   <age>24</age> 
   <salary>5000</salary> 
   <commission>
    3000
   </commission> 
  </vendor> 
  <vendor 
     id="john" 
     manager="fbogus"> 
   <age/> 
   <salary>10000</salary> 
  </vendor>
</result> 
In our next example, we restrict the output by use of a condition in the where clause of the query:
select v
from v in vendors/vendor
where v/age <= 24;
<result>
    <vendor id="mike" manager="fbogus" > 
        <age> 24 </age> 
        <salary> 5000 </salary>   
        <commission> 3000 </commission>
    </vendor> 
</result>
In general, the semantics of a query select E from B where P is defined in three steps. The first deals with from, the second with where and the third with select. Assume that B defines three variables X, Y and Z. In the first step, we find the step of all bindings of those variables specified by B. In the second step, we filter the bindings that satisfy P. In the last step, we construct the expression which form the result.

More formally, the general form of a select-from-where construct is:

select e1(Y,X) ,..., em(Y,X)
from x1 in b1(Y), x2 in b2(Y,x1) ,..., xn in bn(Y,x1,..,xn-1)
where p(Y,X)
where Y=(y1,..,yk) denotes the set of variables defined outside the scope of this expression. In the particuliar case of a standalone query, Y denotes the datasource.

X=(x1,...,xn) denotes the set of variables defined in the from clause.

p is a boolean expression depending on the variable sets X and Y. e1,...,em are X-OQL queries depending on the variable sets X and Y. b1,...,bn are X-OQL queries depending respectively on variables (y1,...,yk),...,(y1,...,yk,x1,...,xn-1).

2.5  Predicates

The where clause can be used to define any predicate, that serves to select data matching the predicate. Complex conditions can be expressed using the boolean negation not and the boolean connectors and, or.

2.6  Constructing elements

One can construct new elements, using a construct statement. The basic syntax for constructing a new element is the following query:
<foo> bar </>;
that means "create an element with tag value foo and content bar ". Its result is:
<result>
  <foo> 
    bar 
  </foo>
</result>
Nested constructs can be used, like in:
<foo id="foo1">
  <bar> 
     Hello
  </> 
  , "World"
</>
that produces :
<result>
  <foo id="foo1"> 
    <bar>
      Hello
    </bar>
    World 
  </foo>
</result>
The general form of a construct statement is:
<ename {attname = attvalue }>
[ econtent {, econtent ] }
</>
where ename, econtent, attname and attvalue are valid X-OQL queries.

2.7  Joins

In the from clause, collections that are not directly related can be declared. As in SQL, this allows computation of joins between these collections. This example selects the sales made by each vendor, using a nested query to group them by vendor.
select 
  <v/@id>
    select 
      <sold> p/@reference </>   
    from p in products/product
    where p//vendor = v/@ID
  </>
from v in vendors/vendor;
The meaning of this query is: for each vendor in vendors, denoted as v, create a new element. The name of this element is given by the query v/@id. Its content is the result of the evaluation of the query:
select 
  <sold> p/@reference </>   
from p in products/product
where p//vendor = v/@ID
for each product in products, denoted as p, if the value of one vendor subelement of p equals to the value of v/@id, create an element named sold, containing the value of the reference attribute of p.

The whole query gives for result:
<result>
  <mike>
    <sold> 012458796 </sold>
    <sold> 6987654 </sold>
  </mike>
  <John>
    <sold> 012458796 </sold>
  </John>
</result>

Previous Next Contents