@ADAMRETTER XQUERY FOR
WWW.ADAMRETTER.ORG.UK PROGRAMMERS
HAS ANYONE
HEARD OF
XQUERY?
XQuery IS:
-
XML QUERY LANGUAGE (W3C PR)
-
Declarative & Turing COMPLETE
-
FUNCTIONAL (Strong static/dynamic)
-
Modular (NOT OO)
-
SMALL (118/142 functions)
XQUERY IS NOT:
-
Written in XML
-
Just about XML
-
Just a Query Language
-
Isolated/Esoteric
-
Finished!
Cool things about XQuery
-
Loves the Web
-
Zero Translation Architecture
-
Monadic
-
Extensible
-
Beautiful / Happy Code
XForms
XPath
Neil Armstrong Flickr CC-BY fdecomite
XProc
XQuery is
FLWORs
all the way down
FLWOR Expressions
for
let
where
order by
return
XQuery 3.0 adds:
group by
sliding window
tumbling window
count
FLWOR EXAMPLE (1 OF 2: SOURCE DATA)
<?xml version="1.0" encoding="UTF-8"?>
<products>
<product dept="GARDEN">
<name>20ft Garden Hose</name>
<cost>10.95</cost>
</product>
<product dept="KITCHEN">
<name>Breville Red Pyramid Kettle</name>
<cost>24.95</cost>
</product>
<product dept="GARDEN">
<name>Flymo Extreme</name>
<cost>129.99</cost>
</product>
</products>
FLWOR EXAMPLE (2 OF 2: QUERY)
for $dept-products in //product
group by $dept := $dept-products/@dept
let $value := sum($dept-products/cost)
count $lines
order by $value descending
return
<department>
<code>{string($dept)}</code>
<product-lines>{$lines}</product-lines>
<stock-value>{$value}</stock-value>
</department>
FLWOR EXAMPLE 2
for $dept-products in //product
group by $dept := $dept-products/@dept
let $value := sum($dept-products/cost)
count $lines
order by $value descending
return
<department>
<code>{string($dept)}</code>
<product-lines>{$lines}</product-lines>
<stock-value>{$value}</stock-value>
<products>
{
$dept-products ! <product>{element()}</product>
}
</products>
</department>
XQuery for HTML5
declare namespace output =
"http://www.w3.org/2010/xslt-xquery-serialization";
declare option output:method "html";
declare option output:html-version "5.0";
declare option output:encoding "UTF-8";
declare option output:indent "yes";
<html>
<head><title>Departmental Report</title></head>
<body>
{
for $dept-products in //product
group by $dept := $dept-products/@dept
let $value := sum($dept-products/cost)
count $lines
order by $value descending
return
<div class="department">
<h2>{string($dept)}</h2>
<div>Product Lines: <span>{$lines}</span></div>
<div>Stock Value: <span>{$value}</span></div>
<ul>
{
$dept-products ! <li>{name/text()}
Cost: £{cost/text()}</li>
}
</ul>
</div>
}
</body>
</html>
XQuery for HTML5 ++ RDFa
declare namespace output =
"http://www.w3.org/2010/xslt-xquery-serialization";
declare option output:method "html";
declare option output:html-version "5.0";
declare option output:encoding "UTF-8";
declare option output:indent "yes";
<html version="HTML+RDFa 1.1"
prefix="dc: http://purl.org/dc/terms/">
<head profile="http://www.w3.org/1999/xhtml/vocab">
<title>Departmental Report</title>
<base href="http://company.com/"/>
<meta property="dc:creator" href="http://www.adamretter.org.uk/#me"/>
<meta property="dc:subject" href="http://company.com/departments/"/>
</head>
<body>
{
for $dept-products in //product
group by $dept := $dept-products/@dept
let $value := sum($dept-products/cost)
count $lines
order by $value descending
return
<section class="department" about="#{$dept}" rel="dc:subject">
<h2>{string($dept)}</h2>
<div>Product Lines: <span>{$lines}</span></div>
<div>Stock Value: <span>{$value}</span></div>
<ul>
{
$dept-products !
<li vocab="http://rdf.data-vocabulary.org/#" typeof="Product">
<span property="name">{name/text()}</span>
Cost: <meta property="currency" content="GBP"/>£
<span property="price">{cost/text()}</span>
</li>
}
</ul>
</section>
}
</body>
</html>
Erm...
I don't see
any JSON yet!
JSON, the STANDARD WAY?
declare namespace output =
"http://www.w3.org/2010/xslt-xquery-serialization";
import module namespace xqjson = "http://xqilla.sourceforge.net/lib/xqjson" at "xqjson.xquery";
declare option output:method "text";
declare option output:encoding "UTF-8";
xqjson:serialize-json(
<json type="array">
{
for $dept-products in //product
group by $dept := $dept-products/@dept
return
<pair name="department" type="object">
<pair name="code" type="string">{string($dept)}</pair>
<pair name="products" type="array">
{
$dept-products !
<pair name="product" type="object">
{
element() !
<pair name="{local-name(.)}" type="string">{text()}</pair>
}
}
</pair>
</pair>
}
</json>
)
JSON, THE EASY WAY*
declare namespace output =
"http://www.w3.org/2010/xslt-xquery-serialization";
declare option output:method "json";
declare option output:encoding "UTF-8";
<departments>
{
for $dept-products in //product
group by $dept := $dept-products/@dept
return
<department>
<code>{string($dept)}</code>
<products>
{
$dept-products ! <product>{element()}</product>
}
</products>
</department>
}
</departments>
* XQuery
is only a
specification
Implementations
-
Vary Wildly!
-
W3C Compliance?
-
Indexing and Optimisation
-
Embedded / Standalone / Server / APIs?
-
Extensions / EXQuery / EXPath etc.
Implementations: I/O
-
Initial Document Set (Static Context)?
-
fn:doc() / fn:collection() / fn:unparsed-text()
-
Update?
-
Side-effects?
-
Expression: Outputs to where?
Implementations
-
C++: XQilla / QtXmlPatterns
-
Java: JDK / eXist / Saxon
-
Objective C: NSXML
-
SQL/XML: Oracle / DB2 / SQLServer
-
NXD: eXist / BaseX / Marklogic / Zorba
I thought we were
talking about
JSON?
JSONiq
-
XQuery ++ JSON
-
Extends XDM with JSON types:
-
Atomic: string, integer, decimal, double, boolean, null
-
Item: Array, Object
-
More natural for JScripters: '.' not '/'
-
MongoDB/Couchbase/JDBC
-
See: JSONiq.org / Zorba.io
JSON the JSONiq way
jsoniq version "1.0";
let $products := [
{ dept: "GARDEN", name: "20ft Garden Hose", cost: 10.95 },
{ dept: "KITCHEN", name: "Breville Red Pyramid Kettle", cost: 24.95 },
{ dept: "GARDEN", name: "Flymo Extreme", cost: 129.99 }
] return
for $dept-products in $products()
group by $dept := $dept-products.dept
let $value := sum($dept-products.cost)
count $lines
order by $value descending
return
{
code: $dept,
product-lines: $lines,
stock-value: $value,
products: $dept-products ! project($$, ("name", "cost"))
}
STANDARDS STATUS
"You keep using this word, ‘
standard’.
W3CMemes does not think it means what you think it does."
Standards status
- XQuery 3.0
- W3C Proposed Recommendation Oct 2013
- ...W3C Recommendation... any time now!
- Several implementations
- JSONiq 1.0
- jsoniq.org: 28msec/IBM/Oracle
- 4 implementations, so far...
- XQuery 3.1
- W3C Internal working draft
- + JSON: Influenced by JSONiq
- + Map type
- + More HoF stuff e.g. =>
- Time frame: 2015
- Few experimental implementations