XQuery tutorial - basics: Difference between revisions

The educational technology and digital learning wiki
Jump to navigation Jump to search
mNo edit summary
No edit summary
Line 33: Line 33:
: [http://www.w3.org/TR/xqueryx/ XML Syntax for XQuery 1.0 (XQueryX)] (barely eadable for humans, but practical for machine parsing of query statements).
: [http://www.w3.org/TR/xqueryx/ XML Syntax for XQuery 1.0 (XQueryX)] (barely eadable for humans, but practical for machine parsing of query statements).
: Authors of this standard: [http://www.w3.org/XML/Query/ W3C XML Query Group]
: Authors of this standard: [http://www.w3.org/XML/Query/ W3C XML Query Group]
== Introductory examples ==
''''Find all nodes with path //topic/title''''
The following expression returns all fragments '''<topic><title>xxxx </title>'''</topic> from anywhere in the tree
for $t in //topic/title
    return $t
''''Find all nodes of //topic/title in "catalog.xml"''''
for $t in document("catalog.xml")//topic/title
    return $t
''''same, but via HTTP''''
for $t in document("http://tecfa.unige.ch/proj/seed/catalog/net/catalog.xml")//topic/title
    return $t
Result
<title>TECFA Seed Catalog</title>
<title>Introduction</title>
<title>Conceptual and technical framework</title>
<title>The socio-constructivist  .... etc.


== Use contexts ==
== Use contexts ==
Line 91: Line 65:


  //c3msbrick/title/text()
  //c3msbrick/title/text()
Let's now examine a few simple XQuery examples:
'''Find all nodes with path //topic/title''': The following expression returns all fragments '''<topic><title>xxxx </title>'''</topic> from anywhere in the tree
for $t in //topic/title
    return $t
The example shows how to '''find all nodes of //topic/title in a file called "catalog.xml"''':
for $t in document("catalog.xml")//topic/title
    return $t
The next example does the same, but retrieves the file via HTTP''':
for $t in document("http://tecfa.unige.ch/proj/seed/catalog/net/catalog.xml")//topic/title
    return $t
Result for all examples
<source lang="xml">
<title>TECFA Seed Catalog</title>
<title>Introduction</title>
<title>Conceptual and technical framework</title>
<title>The socio-constructivist  .... etc.
</source>


== FLWOR expressions ==
== FLWOR expressions ==
: FLOWR = "For-Let-Where-Order-Return"
: Similar to select-from-where-..-order-by of SQL


'''Overview:'''
Let's now introduce the core construct of a typical XQeury expression and which is known under the name '''FLOWR''', which stands for "For-Let-Where-Order-Return"
 
This construct is similar to select-from-where-..-order-by that is used in [[SQL]].
 
'''The FLOWR elements:'''


: for = iteration on a list of XML nodes
: for = iteration on a list of XML nodes
Line 104: Line 106:
: return = expression that will be returned
: return = expression that will be returned


'''For '''
'''For ''':
  for $variable in expression_search
  for $variable in expression_search
  RETURN $variable
  RETURN $variable


"for" associates to $variable each XML fragment found with the XPath (see The query expression)
"for" associates to $variable each XML fragment found ''expression'', defined as XPath expression.
 


Example:
Example:
Line 115: Line 116:
  for $t in //topic/title return $t
  for $t in //topic/title return $t


: '''let'''
'''let''':
: "let" assigns a value (node) to a variable
: "let" assigns a value (node) to a variable
: Example without let:
 
Example without let:


  for $t in document("catalog09.xml")//c3msbrick//c3mssoft-desc//card-propvalue
  for $t in document("catalog09.xml")//c3msbrick//c3mssoft-desc//card-propvalue
  return $t
  return $t


: Same example with let
Same example with let
: for each node $t found, we bind $desc with a subnode.
: for each node $t found, we bind $desc with a subnode.


Line 129: Line 131:
  return $desc
  return $desc


: Counting, for each node $t found in the "for" loop we count the number of subnodes:
Counting, for each node $t found in the "for" loop we count the number of subnodes:


  for $t in document("catalog09.xml")//c3msbrick
  for $t in document("catalog09.xml")//c3msbrick
Line 135: Line 137:
  return <result> {$t/title/text()} owns {$n} bricks </result>
  return <result> {$t/title/text()} owns {$n} bricks </result>


: '''where '''
'''where '''
: defines a selection condition
: defines a selection condition
: Same as above, but we only return results with a least 2 '''<c3mssoft>'''
 
Same as above, but we only return results with a least 2 ''c3mssoft''


  for $t in document("catalog09.xml")//c3msbrick
  for $t in document("catalog09.xml")//c3msbrick
Line 144: Line 147:
  return <result> {$t/title/text()} owns {$n} bricks </result>
  return <result> {$t/title/text()} owns {$n} bricks </result>


: '''order'''
'''Order''':
: Can sort results
: Can sort results
: Alphabetic sorting:
 
Example of an alphabetic sorting:


  for $t in //topic/title '''order by $t''' return $t
  for $t in //topic/title '''order by $t''' return $t


: Alphabetic sorting
More complex alphabetic sorting example:


  for $t in document("catalog09.xml")//c3msbrick
  for $t in document("catalog09.xml")//c3msbrick
Line 158: Line 162:
  return <result> {$t/title/text()} owns {$n} bricks </result>
  return <result> {$t/title/text()} owns {$n} bricks </result>


: Slightly more complex return clause, we also include <titles> of <c3msbricks>:
Below is a slightly more complex return clause, we also include <titles> of <c3msbricks>:


  for $t in document("catalog09.xml")//c3msbrick
  for $t in document("catalog09.xml")//c3msbrick
Line 171: Line 175:


: ''return'' builds the expression to return
: ''return'' builds the expression to return
: Warning: Each iteration must return a fragment, i.e. a single node (and not a collection!)
: Warning: Each iteration must return a fragment, i.e. a '''single node''' (and not a collection!)


Good:
Good:
Line 187: Line 191:
  return $t/title/text() owns $n bricks  
  return $t/title/text() owns $n bricks  


: '''Building XML fragments'''
== Some XQuery tricks ==
: Result of an xquery usually should lead to a single node (not a list)
 
: '''Multi-fragment version (collection)'''
=== About creating XML fragments ===


Consider the following expression
Result of an XQuery usually should lead to a single node (not a list).
Let's first look at a '''Multi-fragment version (collection)''':


  for $t in //c3msbrick/title
  for $t in //c3msbrick/title
     return $t
     return $t


It will return a list (a collection)
This will return a list (a so-called collection)


  1    <title class ="- topic/title " > TECFA Seed Catalog </ title >
  1    <title class ="- topic/title " > TECFA Seed Catalog </ title >
Line 204: Line 209:
  ....
  ....


: This sort of list is not well-formed XML, and can not be displayed in a browser for example.
This sort of list is not well-formed XML, and can not be displayed in a browser for example.
: ... but this is not a problem if is dealt with by some program (e.g. a php script querying a DOM tree)
: ... but this is not a problem if is dealt with by some program (e.g. a php script querying a DOM tree)
: '''Version single fragment'''


The following expression:
Now let's see the '''single fragment''' version. The following expression:


<source lang="xml">
<source lang="xml">
Line 231: Line 235:
: We replaced "title" tags by "titre" tags (just to make this a bit more complicated)
: We replaced "title" tags by "titre" tags (just to make this a bit more complicated)
: All expression within { ...} are evaluated  
: All expression within { ...} are evaluated  
: but all <tags> are copied as is ...
: but all ''tags'' are copied as is ...
: '''For within for'''
 
: you may have loops within loops...
=== For within for ===
 
You may have loops within loops as the following example shows:
 
<source lang="xml">
<source lang="xml">
  <result>
  <result>

Revision as of 19:46, 6 February 2010

Draft

This article or section is currently under construction

In principle, someone is working on it and there should be a better version in a not so distant future.
If you want to modify this page, please discuss it with the person working on it (see the "history")

Introduction

This is a beginners tutorial for XQuery.

Prerequisites:

Recommended reading, before this:

XQuery is an XML language for querying XML that can handle the following XML document types (both single documents or collections):

files
XML databases
XML fragments in memory (e.g. DOM trees)

XQuery can express queries across all these kinds of data, whether physically stored in XML or viewed as XML via middleware. In other words, you can use it to retrieve things from files, from XML representations made from SQL databases, from native XML databases like eXist. In addition, Xquery is quite a real programming language.

In more simple terms, the W3C XML Query Working Group advertized that “XQuery is a standardized language for combining documents, databases, Web pages and almost anything else. It is very widely implemented. It is powerful and easy to learn. XQuery is replacing proprietary middleware languages and Web Application development languages. XQuery is replacing complex Java or C++ programs with a few lines of code. XQuery is simpler to work with and easier to maintain than many other alternatives. Do more with less.”

XQuery

Relies on the Xpath (version 2.0) language
Can generate new XML documents
XQuery does not define updating, see XQupdat (as of Jan 2010 still not a full recommendation, but widely implemented)

Standards:

http://www.w3.org/TR/xquery/ (XQuery 1.0: An XML Query Language, W3C Recommendation 23 January 2007query language, stable)
http://www.w3.org/TR/xqupdate/ (XQuery Update Facility 1.0, W3C Candidate Recommendation 09 June 2009)
XML Syntax for XQuery 1.0 (XQueryX) (barely eadable for humans, but practical for machine parsing of query statements).
Authors of this standard: W3C XML Query Group

Use contexts

You need an XQuery processor
included in some command line/library products like “saxon”
included in XML databases.
included in an XML editor
included in some programming languages

Same principle as for SQL

From the command line
With an administration tool (Web or local)
Trough an other web application)

Basic XQuery

Let's recall that XQuery uses XPath elements. Below are some simple examples:

position in a tree
ex: returns all nodes <card-propvalue> under <c3mssoft-desc> ...
//c3msbrick//c3mssoft-desc//card-propvalue
comparison
ex: returns all nodes with this id
//c3msbrick//c3mssoft[@id="epbl"]
functions
ex: only returns the content of a node
//c3msbrick/title/text()

Let's now examine a few simple XQuery examples:

Find all nodes with path //topic/title: The following expression returns all fragments <topic><title>xxxx </title></topic> from anywhere in the tree

for $t in //topic/title
   return $t 

The example shows how to find all nodes of //topic/title in a file called "catalog.xml":

for $t in document("catalog.xml")//topic/title
   return $t 

The next example does the same, but retrieves the file via HTTP:

for $t in document("http://tecfa.unige.ch/proj/seed/catalog/net/catalog.xml")//topic/title
   return $t 

Result for all examples

 <title>TECFA Seed Catalog</title>
 <title>Introduction</title>
 <title>Conceptual and technical framework</title>
 <title>The socio-constructivist  .... etc.

FLWOR expressions

Let's now introduce the core construct of a typical XQeury expression and which is known under the name FLOWR, which stands for "For-Let-Where-Order-Return"

This construct is similar to select-from-where-..-order-by that is used in SQL.

The FLOWR elements:

for = iteration on a list of XML nodes
let = binding of a result to a local variable
where = selection condition
order = sorting
return = expression that will be returned

For :

for $variable in expression_search
RETURN $variable

"for" associates to $variable each XML fragment found expression, defined as XPath expression.

Example:

for $t in //topic/title return $t

let:

"let" assigns a value (node) to a variable

Example without let:

for $t in document("catalog09.xml")//c3msbrick//c3mssoft-desc//card-propvalue
return $t

Same example with let

for each node $t found, we bind $desc with a subnode.
for $t in document("catalog09.xml")//c3msbrick
  let $desc := $t//c3mssoft-desc//card-propvalue
return $desc

Counting, for each node $t found in the "for" loop we count the number of subnodes:

for $t in document("catalog09.xml")//c3msbrick
let $n := count($t//c3mssoft)
return <result> {$t/title/text()} owns {$n} bricks </result>

where

defines a selection condition

Same as above, but we only return results with a least 2 c3mssoft

for $t in document("catalog09.xml")//c3msbrick
  let $n := count($t//c3mssoft)
  where ($n > 1)
return <result> {$t/title/text()} owns {$n} bricks </result>

Order:

Can sort results

Example of an alphabetic sorting:

for $t in //topic/title order by $t return $t

More complex alphabetic sorting example:

for $t in document("catalog09.xml")//c3msbrick
let $n := count($t//c3mssoft)
where ($n > 1)
order by $n
return <result> {$t/title/text()} owns {$n} bricks </result>

Below is a slightly more complex return clause, we also include <titles> of <c3msbricks>:

for $t in document("catalog09.xml")//c3msbrick
let $brick_softs := $t//c3mssoft
let $n := count($brick_softs)
where ($n > 0)
order by $n
return <result> 
      For {$t/title/text()} we found {$n} softwares: 
         {$brick_softs//title} 
      </result>
return builds the expression to return
Warning: Each iteration must return a fragment, i.e. a single node (and not a collection!)

Good:

for $t in document("catalog09.xml")//c3msbrick
let $n := count($t//c3mssoft)
return <result> 
       {$t/title/text()} owns {$n} bricks 
       </result>

Bad:

for $t in document("catalog09.xml")//c3msbrick
let $n := count($t//c3mssoft)
return $t/title/text() owns $n bricks 

Some XQuery tricks

About creating XML fragments

Result of an XQuery usually should lead to a single node (not a list). Let's first look at a Multi-fragment version (collection):

for $t in //c3msbrick/title
   return $t

This will return a list (a so-called collection)

1    <title class ="- topic/title " > TECFA Seed Catalog </ title >
2    <title class ="- topic/title " > Introduction </ title >
3    <title class ="- topic/title " > Conceptual and technical framework </ title >
4    <title class ="- topic/title " > The socio-constructivist approach </ title >
....

This sort of list is not well-formed XML, and can not be displayed in a browser for example.

... but this is not a problem if is dealt with by some program (e.g. a php script querying a DOM tree)

Now let's see the single fragment version. The following expression:

 <result> 
  { for $t in //topic/title/text()
  return <titre>{$t}</titre> }
 </result>

returns:

 <result  >
 <titre > TECFA Seed Catalog </ titre >
 <titre > Introduction </ titre >
 <titre > Conceptual and technical framework </ titre >
 <titre > The socio-constructivist approach </ titre > 
 ....
 </result>
We replaced "title" tags by "titre" tags (just to make this a bit more complicated)
All expression within { ...} are evaluated
but all tags are copied as is ...

For within for

You may have loops within loops as the following example shows:

 <result>
 <title>List of C3MSBricks and associated Software</title>
 { for $t in document("catalog09.xml")//c3msbrick
   let $brick_softs := $t//c3mssoft
   let $n := count($brick_softs)
   where ($n > 0)
   order by $n descending
   return 
     <brick> Pour {$t/title/text()} on a les {$n} modules suivants:
        { for $soft in $brick_softs
          return <soft> {$soft//title/text()}</soft>
        }
     </brick>
 }
 </result>
Each FLWOR expression is within { ... }
The "return" clause of the outer loop includes a loop that will deal with
$brick_softs contains a collection of $softs from which we extract titles
We also sort the results

Result:

 <result  >
  <title > List of C3MSBricks and associated Software </ title >
  <brick > Gallery owns les 5 bricks suivants:
    <soft > PhotoShare </ soft >
    <soft > Photoshare combined with PageSetter </ soft >
    <soft > My_eGallery </ soft >
    <soft > Coppermine </ soft >
    <soft > Gallery </ soft >
  </ brick >
 <brick > User statistics owns les 5 bricks suivants:
    <soft > commArt </ soft >
    <soft > pncUserPoints </ soft >
    <soft > pncSimpleStats </ soft >
    <soft > Statistics module </ soft >
    <soft > NS-User_Points </ soft >
 </ brick > 
 .....
 </result>

Links

Software and standards

See the XQuery article.

According to the W3C, there are over 40 different software packages that support XML Query in some way.

XQuery Tutorials

XQuery Web sites