~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to doc/src/xquery-introduction.qdoc

  • Committer: Bazaar Package Importer
  • Author(s): Alessandro Ghersi
  • Date: 2009-11-02 18:30:08 UTC
  • mfrom: (1.2.2 upstream)
  • mto: (15.2.5 experimental)
  • mto: This revision was merged to the branch mainline in revision 88.
  • Revision ID: james.westby@ubuntu.com-20091102183008-b6a4gcs128mvfb3m
Tags: upstream-4.6.0~beta1
ImportĀ upstreamĀ versionĀ 4.6.0~beta1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/****************************************************************************
2
 
**
3
 
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4
 
** Contact: Nokia Corporation (qt-info@nokia.com)
5
 
**
6
 
** This file is part of the documentation of the Qt Toolkit.
7
 
**
8
 
** $QT_BEGIN_LICENSE:LGPL$
9
 
** Commercial Usage
10
 
** Licensees holding valid Qt Commercial licenses may use this file in
11
 
** accordance with the Qt Commercial License Agreement provided with the
12
 
** Software or, alternatively, in accordance with the terms contained in
13
 
** a written agreement between you and Nokia.
14
 
**
15
 
** GNU Lesser General Public License Usage
16
 
** Alternatively, this file may be used under the terms of the GNU Lesser
17
 
** General Public License version 2.1 as published by the Free Software
18
 
** Foundation and appearing in the file LICENSE.LGPL included in the
19
 
** packaging of this file.  Please review the following information to
20
 
** ensure the GNU Lesser General Public License version 2.1 requirements
21
 
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22
 
**
23
 
** In addition, as a special exception, Nokia gives you certain
24
 
** additional rights. These rights are described in the Nokia Qt LGPL
25
 
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26
 
** package.
27
 
**
28
 
** GNU General Public License Usage
29
 
** Alternatively, this file may be used under the terms of the GNU
30
 
** General Public License version 3.0 as published by the Free Software
31
 
** Foundation and appearing in the file LICENSE.GPL included in the
32
 
** packaging of this file.  Please review the following information to
33
 
** ensure the GNU General Public License version 3.0 requirements will be
34
 
** met: http://www.gnu.org/copyleft/gpl.html.
35
 
**
36
 
** If you are unsure which license is appropriate for your use, please
37
 
** contact the sales department at http://www.qtsoftware.com/contact.
38
 
** $QT_END_LICENSE$
39
 
**
40
 
****************************************************************************/
41
 
 
42
 
/*!
43
 
    \page xquery-introduction.html
44
 
    \title A Short Path to XQuery
45
 
    \ingroup scripting
46
 
 
47
 
    \startpage index.html QtReference Documentation
48
 
    \target XQuery-introduction
49
 
 
50
 
XQuery is a language for querying XML data or non-XML data that can be
51
 
modeled as XML. XQuery is specified by the \l{http://www.w3.org}{W3C}.
52
 
 
53
 
\tableofcontents
54
 
 
55
 
\section1 Introduction
56
 
 
57
 
Where Java and C++ are \e{statement-based} languages, the XQuery
58
 
language is \e{expression-based}. The simplest XQuery expression is an
59
 
XML element constructor:
60
 
 
61
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 20
62
 
 
63
 
This \c{<recipe/>} element is an XQuery expression that forms a
64
 
complete XQuery. In fact, this XQuery doesn't actually query
65
 
anything. It just creates an empty \c{<recipe/>} element in the
66
 
output. But \l{Constructing Elements} {constructing new elements in an
67
 
XQuery} is often necessary.
68
 
 
69
 
An XQuery expression can also be enclosed in curly braces and embedded
70
 
in another XQuery expression. This XQuery has a document expression
71
 
embedded in a node expression:
72
 
 
73
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 21
74
 
 
75
 
It creates a new \c{<html>} element in the output and sets its \c{id}
76
 
attribute to be the \c{id} attribute from an \c{<html>} element in the
77
 
\c{other.html} file.
78
 
 
79
 
\section1 Using Path Expressions To Match & Select Items
80
 
 
81
 
In C++ and Java, we write nested \c{for} loops and recursive functions
82
 
to traverse XML trees in search of elements of interest. In XQuery, we
83
 
write these iterative and recursive algorithms with \e{path
84
 
expressions}.
85
 
 
86
 
A path expression looks somewhat like a typical \e{file pathname} for
87
 
locating a file in a hierarchical file system. It is a sequence of one
88
 
or more \e{steps} separated by slash '/' or double slash '//'.
89
 
Although path expressions are used for traversing XML trees, not file
90
 
systems, in QtXmlPatterms we can model a file system to look like an
91
 
XML tree, so in QtXmlPatterns we can use XQuery to traverse a file
92
 
system. See the \l {File System Example} {file system example}.
93
 
 
94
 
Think of a path expression as an algorithm for traversing an XML tree
95
 
to find and collect items of interest. This algorithm is evaluated by
96
 
evaluating each step moving from left to right through the sequence. A
97
 
step is evaluated with a set of input items (nodes and atomic values),
98
 
sometimes called the \e focus.  The step is evaluated for each item in
99
 
the focus. These evaluations produce a new set of items, called the \e
100
 
result, which then becomes the focus that is passed to the next step.
101
 
Evaluation of the final step produces the final result, which is the
102
 
result of the XQuery.  The items in the result set are presented in
103
 
\l{http://www.w3.org/TR/xquery/#id-document-order} {document order}
104
 
and without duplicates.
105
 
 
106
 
With QtXmlPatterns, a standard way to present the initial focus to a
107
 
query is to call QXmlQuery::setFocus(). Another common way is to let
108
 
the XQuery itself create the initial focus by using the first step of
109
 
the path expression to call the XQuery \c{doc()} function. The
110
 
\c{doc()} function loads an XML document and returns the \e {document
111
 
node}. Note that the document node is \e{not} the same as the
112
 
\e{document element}. The \e{document node} is a node constructed in
113
 
memory, when the document is loaded. It represents the entire XML
114
 
document, not the document element. The \e{document element} is the
115
 
single, top-level XML element in the file. The \c{doc()} function
116
 
returns the document node, which becomes the singleton node in the
117
 
initial focus set. The document node will have one child node, and
118
 
that child node will represent the document element.  Consider the
119
 
following XQuery:
120
 
 
121
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 18
122
 
 
123
 
The \c{doc()} function loads the file \l{cookbook.xml} and returns the
124
 
document node. The document node then becomes the focus for the next
125
 
step \c{//recipe}. Here the double slash means select all \c{<recipe>}
126
 
elements found below the document node, regardless of where they
127
 
appear in the document tree.  The query selects all \c{<recipe>}
128
 
elements in the cookbook. See \l{Running The Cookbook Examples} for
129
 
instructions on how to run this query (and most of the ones that
130
 
follow) from the command line.
131
 
 
132
 
Conceptually, evaluation of the steps of a path expression is similar
133
 
to iterating through the same number of nested \e{for} loops. Consider
134
 
the following XQuery, which builds on the previous one:
135
 
 
136
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 19
137
 
 
138
 
This XQuery is a single path expression composed of three steps. The
139
 
first step creates the initial focus by calling the \c{doc()}
140
 
function. We can paraphrase what the query engine does at each step:
141
 
 
142
 
\list 1
143
 
    \o for each node in the initial focus (the document node)...
144
 
    \o for each descendant node that is a \c{<recipe>} element...
145
 
    \o collect the child nodes that are \c{<title>} elements.
146
 
\endlist
147
 
 
148
 
Again the double slash means select all the \c{<recipe>} elements in the
149
 
document. The single slash before the \c{<title>} element means select
150
 
only those \c{<title>} elements that are \e{child} elements of a
151
 
\c{<recipe>} element (i.e. not grandchildren, etc). The XQuery evaluates
152
 
to a final result set containing the \c{<title>} element of each
153
 
\c{<recipe>} element in the cookbook.
154
 
 
155
 
\section2 Axis Steps
156
 
 
157
 
The most common kind of path step is called an \e{axis step}, which
158
 
tells the query engine which way to navigate from the context node,
159
 
and which test to perform when it encounters nodes along the way. An
160
 
axis step has two parts, an \e{axis specifier}, and a \e{node test}.
161
 
Conceptually, evaluation of an axis step proceeds as follows: For each
162
 
node in the focus set, the query engine navigates out from the node
163
 
along the specified axis and applies the node test to each node it
164
 
encounters. The nodes selected by the node test are collected in the
165
 
result set, which becomes the focus set for the next step.
166
 
 
167
 
In the example XQuery above, the second and third steps are both axis
168
 
steps. Both apply the \c{element(name)} node test to nodes encountered
169
 
while traversing along some axis. But in this example, the two axis
170
 
steps are written in a \l{Shorthand Form} {shorthand form}, where the
171
 
axis specifier and the node test are not written explicitly but are
172
 
implied. XQueries are normally written in this shorthand form, but
173
 
they can also be written in the longhand form. If we rewrite the
174
 
XQuery in the longhand form, it looks like this:
175
 
 
176
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 22
177
 
 
178
 
The two axis steps have been expanded. The first step (\c{//recipe})
179
 
has been rewritten as \c{/descendant-or-self::element(recipe)}, where
180
 
\c{descendant-or-self::} is the axis specifier and \c{element(recipe)}
181
 
is the node test. The second step (\c{title}) has been rewritten as
182
 
\c{/child::element(title)}, where \c{child::} is the axis specifier
183
 
and \c{element(title)} is the node test. The output of the expanded
184
 
XQuery will be exactly the same as the output of the shorthand form.
185
 
 
186
 
To create an axis step, concatenate an axis specifier and a node
187
 
test. The following sections list the axis specifiers and node tests
188
 
that are available.
189
 
 
190
 
\section2 Axis Specifiers
191
 
 
192
 
An axis specifier defines the direction you want the query engine to
193
 
take, when it navigates away from the context node. QtXmlPatterns
194
 
supports the following axes.
195
 
 
196
 
\table
197
 
\header
198
 
  \o Axis Specifier
199
 
  \o refers to the axis containing...
200
 
  \row
201
 
    \o \c{self::}
202
 
    \o the context node itself
203
 
  \row
204
 
    \o \c{attribute::}
205
 
    \o all attribute nodes of the context node
206
 
  \row
207
 
    \o \c{child::}
208
 
    \o all child nodes of the context node (not attributes)
209
 
  \row
210
 
    \o \c{descendant::}
211
 
    \o all descendants of the context node (children, grandchildren, etc)
212
 
  \row
213
 
    \o \c{descendant-or-self::}
214
 
    \o all nodes in \c{descendant} + \c{self}
215
 
  \row
216
 
    \o \c{parent::}
217
 
    \o the parent node of the context node, or empty if there is no parent
218
 
  \row
219
 
    \o \c{ancestor::}
220
 
    \o all ancestors of the context node (parent, grandparent, etc)
221
 
  \row
222
 
    \o \c{ancestor-or-self::}
223
 
    \o all nodes in \c{ancestor} + \c{self}
224
 
  \row
225
 
    \o \c{following::}
226
 
    \o all nodes in the tree containing the context node, \e not
227
 
    including \c{descendant}, \e and that follow the context node
228
 
    in the document
229
 
  \row
230
 
    \o \c{preceding::}
231
 
    \o all nodes in the tree contianing the context node, \e not
232
 
    including \c{ancestor}, \e and that precede the context node in
233
 
    the document
234
 
  \row
235
 
    \o \c{following-sibling::}
236
 
    \o all children of the context node's \c{parent} that follow the
237
 
    context node in the document
238
 
  \row
239
 
    \o \c{preceding-sibling::}
240
 
    \o all children of the context node's \c{parent} that precede the
241
 
    context node in the document
242
 
\endtable
243
 
 
244
 
\section2 Node Tests
245
 
 
246
 
A node test is a conditional expression that must be true for a node
247
 
if the node is to be selected by the axis step. The conditional
248
 
expression can test just the \e kind of node, or it can test the \e
249
 
kind of node and the \e name of the node. The XQuery specification for
250
 
\l{http://www.w3.org/TR/xquery/#node-tests} {node tests} also defines
251
 
a third condition, the node's \e {Schema Type}, but schema type tests
252
 
are not supported in QtXmlPatterns.
253
 
 
254
 
QtXmlPatterns supports the following node tests. The tests that have a
255
 
\c{name} parameter test the node's name in addition to its \e{kind}
256
 
and are often called the \l{Name Tests}.
257
 
 
258
 
\table
259
 
\header
260
 
  \o Node Test
261
 
  \o matches all...
262
 
  \row
263
 
    \o \c{node()}
264
 
    \o nodes of any kind
265
 
  \row
266
 
    \o \c{text()}
267
 
    \o text nodes
268
 
  \row
269
 
    \o \c{comment()}
270
 
    \o comment nodes
271
 
  \row
272
 
    \o \c{element()}
273
 
    \o element nodes (same as star: *)
274
 
  \row
275
 
    \o \c{element(name)}
276
 
    \o element nodes named \c{name}
277
 
  \row
278
 
    \o \c{attribute()}
279
 
    \o attribute nodes
280
 
  \row
281
 
    \o \c{attribute(name)}
282
 
    \o attribute nodes named \c{name}
283
 
   \row
284
 
    \o \c{processing-instruction()}
285
 
    \o processing-instructions
286
 
  \row
287
 
    \o \c{processing-instruction(name)}
288
 
    \o processing-instructions named \c{name}
289
 
  \row
290
 
    \o \c{document-node()}
291
 
    \o document nodes (there is only one)
292
 
  \row
293
 
    \o \c{document-node(element(name))}
294
 
    \o document node with document element \c{name}
295
 
\endtable
296
 
 
297
 
\target Shorthand Form
298
 
\section2 Shorthand Form
299
 
 
300
 
Writing axis steps using the longhand form with axis specifiers and
301
 
node tests is semantically clear but syntactically verbose. The
302
 
shorthand form is easy to learn and, once you learn it, just as easy
303
 
to read. In the shorthand form, the axis specifier and node test are
304
 
implied by the syntax. XQueries are normally written in the shorthand
305
 
form. Here is a table of some frequently used shorthand forms:
306
 
 
307
 
\table
308
 
\header
309
 
  \o Shorthand syntax
310
 
  \o Short for...
311
 
  \o matches all...
312
 
  \row
313
 
    \o \c{name}
314
 
    \o \c{child::element(name)}
315
 
    \o child nodes that are \c{name} elements
316
 
 
317
 
  \row
318
 
    \o \c{*}
319
 
    \o \c{child::element()}
320
 
    \o child nodes that are elements (\c{node()} matches
321
 
    \e all child nodes)
322
 
 
323
 
  \row
324
 
    \o \c{..}
325
 
    \o \c{parent::node()}
326
 
    \o parent nodes (there is only one)
327
 
 
328
 
  \row
329
 
    \o \c{@*}
330
 
    \o \c{attribute::attribute()}
331
 
    \o attribute nodes
332
 
 
333
 
  \row
334
 
    \o \c{@name}
335
 
    \o \c{attribute::attribute(name)}
336
 
    \o \c{name} attributes
337
 
 
338
 
  \row
339
 
    \o \c{//}
340
 
    \o \c{descendant-or-self::node()}
341
 
    \o descendent nodes (when used instead of '/')
342
 
 
343
 
\endtable
344
 
 
345
 
The \l{http://www.w3.org/TR/xquery/}{XQuery language specification}
346
 
has a more detailed section on the shorthand form, which it calls the
347
 
\l{http://www.w3.org/TR/xquery/#abbrev} {abbreviated syntax}. More
348
 
examples of path expressions written in the shorthand form are found
349
 
there. There is also a section listing examples of path expressions
350
 
written in the \l{http://www.w3.org/TR/xquery/#unabbrev} {longhand
351
 
form}.
352
 
 
353
 
\target Name Tests
354
 
\section2 Name Tests
355
 
 
356
 
The name tests are the \l{Node Tests} that have the \c{name}
357
 
parameter. A name test must match the node \e name in addition to the
358
 
node \e kind. We have already seen name tests used:
359
 
 
360
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 19
361
 
 
362
 
In this path expression, both \c{recipe} and \c{title} are name tests
363
 
written in the shorthand form. XQuery resolves these names
364
 
(\l{http://www.w3.org/TR/xquery/#id-basics}{QNames}) to their expanded
365
 
form using whatever
366
 
\l{http://www.w3.org/TR/xquery/#dt-namespace-declaration} {namespace
367
 
declarations} it knows about. Resolving a name to its expanded form
368
 
means replacing its namespace prefix, if one is present (there aren't
369
 
any present in the example), with a namespace URI. The expanded name
370
 
then consists of the namespace URI and the local name.
371
 
 
372
 
But the names in the example above don't have namespace prefixes,
373
 
because we didn't include a namespace declaration in our
374
 
\c{cookbook.xml} file. However, we will often use XQuery to query XML
375
 
documents that use namespaces. Forgetting to declare the correct
376
 
namespace(s) in an XQuery is a common cause of XQuery failures. Let's
377
 
add a \e{default} namespace to \c{cookbook.xml} now. Change the
378
 
\e{document element} in \c{cookbook.xml} from:
379
 
 
380
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 23
381
 
 
382
 
to...
383
 
 
384
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 24
385
 
 
386
 
This is called a \e{default namespace} declaration because it doesn't
387
 
include a namespace prefix. By including this default namespace
388
 
declaration in the document element, we mean that all unprefixed
389
 
\e{element} names in the document, including the document element
390
 
itself (\c{cookbook}), are automatically in the default namespace
391
 
\c{http://cookbook/namespace}. Note that unprefixed \e{attribute}
392
 
names are not affected by the default namespace declaration. They are
393
 
always considered to be in \e{no namespace}.  Note also that the URL
394
 
we choose as our namespace URI need not refer to an actual location,
395
 
and doesn't refer to one in this case. But click on
396
 
\l{http://www.w3.org/XML/1998/namespace}, for example, which is the
397
 
namespace URI for elements and attributes prefixed with \c{xml:}.
398
 
 
399
 
Now when we try to run the previous XQuery example, no output is
400
 
produced! The path expression no longer matches anything in the
401
 
cookbook file because our XQuery doesn't yet know about the namespace
402
 
declaration we added to the cookbook document. There are two ways we
403
 
can declare the namespace in the XQuery. We can give it a \e{namespace
404
 
prefix} (e.g. \c{c} for cookbook) and prefix each name test with the
405
 
namespace prefix:
406
 
 
407
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 3
408
 
 
409
 
Or we can declare the namespace to be the \e{default element
410
 
namespace}, and then we can still run the original XQuery:
411
 
 
412
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 4
413
 
 
414
 
Both methods will work and produce the same output, all the
415
 
\c{<title>} elements:
416
 
 
417
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 5
418
 
 
419
 
But note how the output is slightly different from the output we saw
420
 
before we added the default namespace declaration to the cookbook file.
421
 
QtXmlPatterns automatically includes the correct namespace attribute
422
 
in each \c{<title>} element in the output. When QtXmlPatterns loads a
423
 
document and expands a QName, it creates an instance of QXmlName,
424
 
which retains the namespace prefix along with the namespace URI and
425
 
the local name. See QXmlName for further details.
426
 
 
427
 
One thing to keep in mind from this namespace discussion, whether you
428
 
run XQueries in a Qt program using QtXmlPatterns, or you run them from
429
 
the command line using xmlpatterns, is that if you don't get the
430
 
output you expect, it might be because the data you are querying uses
431
 
namespaces, but you didn't declare those namespaces in your XQuery.
432
 
 
433
 
\section3 Wildcards in Name Tests
434
 
 
435
 
The wildcard \c{'*'} can be used in a name test. To find all the
436
 
attributes in the cookbook but select only the ones in the \c{xml}
437
 
namespace, use the \c{xml:} namespace prefix but replace the
438
 
\e{local name} (the attribute name) with the wildcard:
439
 
 
440
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 7
441
 
 
442
 
Oops! If you save this XQuery in \c{file.xq} and run it through
443
 
\c{xmlpatterns}, it doesn't work. You get an error message instead,
444
 
something like this: \e{Error SENR0001 in file:///...file.xq, at line
445
 
1, column 1: Attribute xml:id can't be serialized because it appears
446
 
at the top level.} The XQuery actually ran correctly. It selected a
447
 
bunch of \c{xml:id} attributes and put them in the result set. But
448
 
then \c{xmlpatterns} sent the result set to a \l{QXmlSerializer}
449
 
{serializer}, which tried to output it as well-formed XML. Since the
450
 
result set contains only attributes and attributes alone are not
451
 
well-formed XML, the \l{QXmlSerializer} {serializer} reports a
452
 
\l{http://www.w3.org/TR/2005/WD-xslt-xquery-serialization-20050915/#id-errors}
453
 
{serialization error}.
454
 
 
455
 
Fear not. XQuery can do more than just find and select elements and
456
 
attributes. It can \l{Constructing Elements} {construct new ones on
457
 
the fly} as well, which is what we need to do here if we want
458
 
\c{xmlpatterns} to let us see the attributes we selected. The example
459
 
above and the ones below are revisited in the \l{Constructing
460
 
Elements} section. You can jump ahead to see the modified examples
461
 
now, and then come back, or you can press on from here.
462
 
 
463
 
To find all the \c{name} attributes in the cookbook and select them
464
 
all regardless of their namespace, replace the namespace prefix with
465
 
the wildcard and write \c{name} (the attribute name) as the local
466
 
name:
467
 
 
468
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 8
469
 
 
470
 
To find and select all the attributes of the \e{document element} in
471
 
the cookbook, replace the entire name test with the wildcard:
472
 
 
473
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 9
474
 
 
475
 
\section1 Using Predicates In Path Expressions
476
 
 
477
 
Predicates can be used to further filter the nodes selected by a path
478
 
expression. A predicate is an expression in square brackets ('[' and
479
 
']') that either returns a boolean value or a number. A predicate can
480
 
appear at the end of any path step in a path expression. The predicate
481
 
is applied to each node in the focus set.  If a node passes the
482
 
filter, the node is included in the result set.  The query below
483
 
selects the recipe element that has the \c{<title>} element
484
 
\c{"Hard-Boiled Eggs"}.
485
 
 
486
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 10
487
 
 
488
 
The dot expression ('.') can be used in predicates and path
489
 
expressions to refer to the current context node. The following query
490
 
uses the dot expression to refer to the current \c{<method>} element.
491
 
The query selects the empty \c{<method>} elements from the cookbook.
492
 
 
493
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 11
494
 
 
495
 
Note that passing the dot expression to the
496
 
\l{http://www.w3.org/TR/xpath-functions/#func-string-length}
497
 
{string-length()} function is optional. When
498
 
\l{http://www.w3.org/TR/xpath-functions/#func-string-length}
499
 
{string-length()} is called with no parameter, the context node is
500
 
assumed:
501
 
 
502
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 12
503
 
 
504
 
Actually, selecting an empty \c{<method>} element might not be very
505
 
useful by itself. It doesn't tell you which recipe has the empty
506
 
method:
507
 
 
508
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 31
509
 
 
510
 
\target Empty Method Not Robust
511
 
What you probably want to see instead are the \c{<recipe>} elements that
512
 
have empty \c{<method>} elements:
513
 
 
514
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 32
515
 
 
516
 
The predicate uses the
517
 
\l{http://www.w3.org/TR/xpath-functions/#func-string-length}
518
 
{string-length()} function to test the length of each \c{<method>}
519
 
element in each \c{<recipe>} element found by the node test. If a
520
 
\c{<method>} contains no text, the predicate evaluates to \c{true} and
521
 
the \c{<recipe>} element is selected. If the method contains some
522
 
text, the predicate evaluates to \c{false}, and the \c{<recipe>}
523
 
element is discarded.  The output is the entire recipe that has no
524
 
instructions for preparation:
525
 
 
526
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 33
527
 
 
528
 
The astute reader will have noticed that this use of
529
 
\c{string-length()} to find an empty element is unreliable. It works
530
 
in this case, because the method element is written as \c{<method/>},
531
 
guaranteeing that its string length will be 0. It will still work if
532
 
the method element is written as \c{<method></method>}, but it will
533
 
fail if there is any whitespace between the opening and ending
534
 
\c{<method>} tags. A more robust way to find the recipes with empty
535
 
methods is presented in the section on \l{Boolean Predicates}.
536
 
 
537
 
There are many more functions and operators defined for XQuery and
538
 
XPath. They are all \l{http://www.w3.org/TR/xpath-functions}
539
 
{documented here}.
540
 
 
541
 
\section2 Positional Predicates
542
 
 
543
 
Predicates are often used to filter items based on their position in
544
 
a sequence. For path expressions processing items loaded from XML
545
 
documents, the normal sequence is
546
 
\l{http://www.w3.org/TR/xquery/#id-document-order} {document order}.
547
 
This query returns the second \c{<recipe>} element in the
548
 
\c{cookbook.xml} file:
549
 
 
550
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 13
551
 
 
552
 
The other frequently used positional function is
553
 
\l{http://www.w3.org/TR/xpath-functions/#func-last} {last()}, which
554
 
returns the numeric position of the last item in the focus set. Stated
555
 
another way, \l{http://www.w3.org/TR/xpath-functions/#func-last}
556
 
{last()} returns the size of the focus set. This query returns the
557
 
last recipe in the cookbook:
558
 
 
559
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 16
560
 
 
561
 
And this query returns the next to last \c{<recipe>}:
562
 
 
563
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 17
564
 
 
565
 
\section2 Boolean Predicates
566
 
 
567
 
The other kind of predicate evaluates to \e true or \e false. A
568
 
boolean predicate takes the value of its expression and determines its
569
 
\e{effective boolean value} according to the following rules:
570
 
 
571
 
\list
572
 
    \o An expression that evaluates to a single node is \c{true}.
573
 
 
574
 
    \o An expression that evaluates to a string is \c{false} if the
575
 
       string is empty and \c{true} if the string is not empty.
576
 
 
577
 
    \o An expression that evaluates to a boolean value (i.e. type
578
 
    \c{xs:boolean}) is that value.
579
 
 
580
 
    \o If the expression evaluates to anything else, it's an error
581
 
    (e.g. type \c{xs:date}).
582
 
 
583
 
\endlist
584
 
 
585
 
We have already seen some boolean predicates in use.  Earlier, we saw
586
 
a \e{not so robust} way to find the \l{Empty Method Not Robust}
587
 
{recipes that have no instructions}. \c{[string-length(method) = 0]}
588
 
is a boolean predicate that would fail in the example if the empty
589
 
method element was written with both opening and closing tags and
590
 
there was whitespace between the tags. Here is a more robust way that
591
 
uses a different boolean predicate.
592
 
 
593
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 34
594
 
 
595
 
This one uses the
596
 
\l{http://www.w3.org/TR/xpath-functions/#func-empty} {empty()} and
597
 
function to test whether the method contains any steps. If the method
598
 
contains no steps, then \c{empty(step)} will return \c{true}, and
599
 
hence the predicate will evaluate to \c{true}.
600
 
 
601
 
But even that version isn't foolproof. Suppose the method does contain
602
 
steps, but all the steps themselves are empty. That's still a case of
603
 
a recipe with no instructions that won't be detected. There is a
604
 
better way:
605
 
 
606
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 35
607
 
 
608
 
This version uses the
609
 
\l{http://www.w3.org/TR/xpath-functions/#func-not} {not} and
610
 
\l{http://www.w3.org/TR/xpath-functions/#func-normalize-space}
611
 
{normalize-space()} functions. \c{normalize-space(method))} returns
612
 
the contents of the method element as a string, but with all the
613
 
whitespace normalized, i.e., the string value of each \c{<step>}
614
 
element will have its whitespace normalized, and then all the
615
 
normalized step values will be concatenated. If that string is empty,
616
 
then \c{not()} returns \c{true} and the predicate is \c{true}.
617
 
 
618
 
We can also use the
619
 
\l{http://www.w3.org/TR/xpath-functions/#func-position} {position()}
620
 
function in a comparison to inspect positions with conditional logic. The
621
 
\l{http://www.w3.org/TR/xpath-functions/#func-position} {position()}
622
 
function returns the position index of the current context item in the
623
 
sequence of items:
624
 
 
625
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 14
626
 
 
627
 
Note that the first position in the sequence is position 1, not 0. We
628
 
can also select \e{all} the recipes after the first one:
629
 
 
630
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 15
631
 
 
632
 
\target Constructing Elements
633
 
\section1 Constructing Elements
634
 
 
635
 
In the section about \l{Wildcards in Name Tests} {using wildcards in
636
 
name tests}, we saw three simple example XQueries, each of which
637
 
selected a different list of XML attributes from the cookbook.  We
638
 
couldn't use \c{xmlpatterns} to run these queries, however, because
639
 
\c{xmlpatterns} sends the XQuery results to a \l{QXmlSerializer}
640
 
{serializer}, which expects to serialize the results as well-formed
641
 
XML. Since a list of XML attributes by itself is not well-formed XML,
642
 
the serializer reported an error for each XQuery.
643
 
 
644
 
Since an attribute must appear in an element, for each attribute in
645
 
the result set, we must create an XML element. We can do that using a
646
 
\l{http://www.w3.org/TR/xquery/#id-for-let} {\e{for} clause} with a
647
 
\l{http://www.w3.org/TR/xquery/#id-variables} {bound variable}, and a
648
 
\l{http://www.w3.org/TR/xquery/#id-orderby-return} {\e{return}
649
 
clause} with an element constructor:
650
 
 
651
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 25
652
 
 
653
 
The \e{for} clause produces a sequence of attribute nodes from the result
654
 
of the path expression. Each attribute node in the sequence is bound
655
 
to the variable \c{$i}. The \e{return} clause then constructs a \c{<p>}
656
 
element around the attribute node. Here is the output:
657
 
 
658
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 28
659
 
 
660
 
The output contains one \c{<p>} element for each \c{xml:id} attribute
661
 
in the cookbook. Note that XQuery puts each attribute in the right
662
 
place in its \c{<p>} element, despite the fact that in the \e{return}
663
 
clause, the \c{$i} variable is positioned as if it is meant to become
664
 
\c{<p>} element content.
665
 
 
666
 
The other two examples from the \l{Wildcards in Name Tests} {wildcard}
667
 
section can be rewritten the same way. Here is the XQuery that selects
668
 
all the \c{name} attributes, regardless of namespace:
669
 
 
670
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 26
671
 
 
672
 
And here is its output:
673
 
 
674
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 29
675
 
 
676
 
And here is the XQuery that selects all the attributes from the
677
 
\e{document element}:
678
 
 
679
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 27
680
 
 
681
 
And here is its output:
682
 
 
683
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 30
684
 
 
685
 
\section2 Element Constructors are Expressions
686
 
 
687
 
Because node constructors are expressions, they can be used in
688
 
XQueries wherever expressions are allowed.
689
 
 
690
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 40
691
 
 
692
 
If \c{cookbook.xml} is loaded without error, a \c{<resept>} element
693
 
(Norweigian word for recipe) is constructed for each \c{<recipe>}
694
 
element in the cookbook, and the child nodes of the \c{<recipe>} are
695
 
copied into the \c{<resept>} element. But if the cookbook document
696
 
doesn't exist or does not contain well-formed XML, a single
697
 
\c{<resept>} element is constructed containing an error message.
698
 
 
699
 
\section1 Constructing Atomic Values
700
 
 
701
 
XQuery also has atomic values. An atomic value is a value in the value
702
 
space of one of the built-in datatypes in the \l
703
 
{http://www.w3.org/TR/xmlschema-2} {XML Schema language}. These
704
 
\e{atomic types} have built-in operators for doing arithmetic,
705
 
comparisons, and for converting values to other atomic types. See the
706
 
\l {http://www.w3.org/TR/xmlschema-2/#built-in-datatypes} {Built-in
707
 
Datatype Hierarchy} for the entire tree of built-in, primitive and
708
 
derived atomic types. \note Click on a data type in the tree for its
709
 
detailed specification.
710
 
 
711
 
To construct an atomic value as element content, enclose an expression
712
 
in curly braces and embed it in the element constructor:
713
 
 
714
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 36
715
 
 
716
 
Sending this XQuery through xmlpatterns produces:
717
 
 
718
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 37
719
 
 
720
 
To compute the value of an attribute, enclose the expression in
721
 
curly braces and embed it in the attribute value:
722
 
 
723
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 38
724
 
 
725
 
Sending this XQuery through xmlpatterns produces:
726
 
 
727
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 39
728
 
 
729
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 40
730
 
 
731
 
If \c{cookbook.xml} is loaded without error, a \c{<resept>} element
732
 
(Norweigian word for recipe) is constructed for each \c{<recipe>}
733
 
element in the cookbook, and the child nodes of the \c{<recipe>} are
734
 
copied into the \c{<resept>} element. But if the cookbook document
735
 
doesn't exist or does not contain well-formed XML, a single
736
 
\c{<resept>} element is constructed containing an error message.
737
 
 
738
 
\section1 Running The Cookbook Examples
739
 
 
740
 
Most of the XQuery examples in this document refer to the cookbook
741
 
written in XML shown below. Save it as \c{cookbook.xml}. In the same
742
 
directory, save one of the cookbook XQuery examples in a \c{.xq} file
743
 
(e.g. \c{file.xq}). Run the XQuery using Qt's command line utility:
744
 
 
745
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 6
746
 
 
747
 
\section2 cookbook.xml
748
 
 
749
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 100
750
 
 
751
 
\section1 Further Reading
752
 
 
753
 
There is much more to the XQuery language than we have presented in
754
 
this short introduction. We will be adding more here in later
755
 
releases. In the meantime, playing with the \c{xmlpatterns} utility
756
 
and making modifications to the XQuery examples provided here will be
757
 
quite informative. An XQuery textbook will be a good investment.
758
 
 
759
 
You can also ask questions on XQuery mail lists:
760
 
 
761
 
\list
762
 
\o
763
 
\l{http://lists.trolltech.com/qt-interest/}{qt-interest}
764
 
\o
765
 
\l{http://www.x-query.com/mailman/listinfo/talk}{talk at x-query.com}.
766
 
\endlist
767
 
 
768
 
\l{http://www.functx.com/functx/}{FunctX} has a collection of XQuery
769
 
functions that can be both useful and educational.
770
 
 
771
 
This introduction contains many links to the specifications, which, of course,
772
 
are the ultimate source of information about XQuery. They can be a bit
773
 
difficult, though, so consider investing in a textbook:
774
 
 
775
 
\list
776
 
 
777
 
    \o \l{http://www.w3.org/TR/xquery/}{XQuery 1.0: An XML Query
778
 
    Language} - the main source for syntax and semantics.
779
 
 
780
 
    \o \l{http://www.w3.org/TR/xpath-functions/}{XQuery 1.0 and XPath
781
 
       2.0 Functions and Operators} - the builtin functions and operators.
782
 
 
783
 
\endlist
784
 
 
785
 
\section1 FAQ
786
 
 
787
 
The answers to these frequently asked questions explain the causes of
788
 
several common mistakes that most beginners make.  Reading through the
789
 
answers ahead of time might save you a lot of head scratching.
790
 
 
791
 
\section2 Why didn't my path expression match anything?
792
 
 
793
 
The most common cause of this bug is failure to declare one or more
794
 
namespaces in your XQuery. Consider the following query for selecting
795
 
all the examples in an XHTML document:
796
 
 
797
 
\quotefile snippets/patternist/simpleHTML.xq
798
 
 
799
 
It won't match anything because \c{index.html} is an XHTML file, and
800
 
all XHTML files declare the default namespace
801
 
\c{"http://www.w3.org/1999/xhtml"} in their top (\c{<html>}) element.
802
 
But the query doesn't declare this namespace, so the path expression
803
 
expands \c{html} to \c{{}html} and tries to match that expanded name.
804
 
But the actual expanded name is
805
 
\c{{http://www.w3.org/1999/xhtml}html}. One possible fix is to declare the
806
 
correct default namespace in the XQuery:
807
 
 
808
 
\quotefile snippets/patternist/simpleXHTML.xq
809
 
 
810
 
Another common cause of this bug is to confuse the \e{document node}
811
 
with the top element node. They are different. This query won't match
812
 
anything:
813
 
 
814
 
\quotefile snippets/patternist/docPlainHTML.xq
815
 
 
816
 
The \c{doc()} function returns the \e{document node}, not the top
817
 
element node (\c{<html>}). Don't forget to match the top element node
818
 
in the path expression:
819
 
 
820
 
\quotefile snippets/patternist/docPlainHTML2.xq
821
 
 
822
 
\section2 What if my input namespace is different from my output namespace?
823
 
 
824
 
Just remember to declare both namespaces in your XQuery and use them
825
 
properly. Consider the following query, which is meant to generate
826
 
XHTML output from XML input:
827
 
 
828
 
\quotefile snippets/patternist/embedDataInXHTML.xq
829
 
 
830
 
We want the \c{<html>}, \c{<body>}, and \c{<p>} nodes we create in the
831
 
output to be in the standard XHTML namespace, so we declare the
832
 
default namespace to be \c{http://www.w3.org/1999/xhtml}. That's
833
 
correct for the output, but that same default namespace will also be
834
 
applied to the node names in the path expression we're trying to match
835
 
in the input (\c{/tests/test[@status = "failure"]}), which is wrong,
836
 
because the namespace used in \c{testResult.xml} is perhaps in the
837
 
empty namespace. So we must declare that namespace too, with a
838
 
namespace prefix, and then use the prefix with the node names in
839
 
the path expression. This one will probably work better:
840
 
 
841
 
\quotefile snippets/patternist/embedDataInXHTML2.xq
842
 
 
843
 
\section2 Why doesn't my return clause work?
844
 
 
845
 
Recall that XQuery is an \e{expression-based} language, not
846
 
\e{statement-based}. Because an XQuery is a lot of expressions,
847
 
understanding XQuery expression precedence is very important.
848
 
Consider the following query:
849
 
 
850
 
\quotefile snippets/patternist/forClause2.xq
851
 
 
852
 
It looks ok, but it isn't. It is supposed to be a FLWOR expression
853
 
comprising a \e{for} clause and a \e{return} clause, but it isn't just
854
 
that. It \e{has} a FLWOR expression, certainly (with the \e{for} and
855
 
\e{return} clauses), but it \e{also} has an arithmetic expression
856
 
(\e{+ $d}) dangling at the end because we didn't enclose the return
857
 
expression in parentheses.
858
 
 
859
 
Using parentheses to establish precedence is more important in XQuery
860
 
than in other languages, because XQuery is \e{expression-based}. In
861
 
In this case, without parantheses enclosing \c{$i + $d}, the return
862
 
clause only returns \c{$i}. The \c{+$d} will have the result of the
863
 
FLWOR expression as its left operand. And, since the scope of variable
864
 
\c{$d} ends at the end of the \e{return} clause, a variable out of
865
 
scope error will be reported. Correct these problems by using
866
 
parentheses.
867
 
 
868
 
\quotefile snippets/patternist/forClause.xq
869
 
 
870
 
\section2 Why didn't my expression get evaluated?
871
 
 
872
 
You probably misplaced some curly braces. When you want an expression
873
 
evaluated inside an element constructor, enclose the expression in
874
 
curly braces. Without the curly braces, the expression will be
875
 
interpreted as text. Here is a \c{sum()} expression used in an \c{<e>}
876
 
element. The table shows cases where the curly braces are missing,
877
 
misplaced, and placed correctly:
878
 
 
879
 
\table
880
 
\header
881
 
  \o element constructor with expression...
882
 
  \o evaluates to...
883
 
  \row
884
 
    \o <e>sum((1, 2, 3))</e>
885
 
    \o <e>sum((1, 2, 3))</e>
886
 
  \row
887
 
    \o <e>sum({(1, 2, 3)})</e>
888
 
    \o <e>sum(1 2 3)</e>
889
 
  \row
890
 
    \o <e>{sum((1, 2, 3))}</e>
891
 
    \o <e>6</e>
892
 
\endtable
893
 
 
894
 
\section2 My predicate is correct, so why doesn't it select the right stuff?
895
 
 
896
 
Either you put your predicate in the wrong place in your path
897
 
expression, or you forgot to add some parentheses.  Consider this
898
 
input file \c{doc.txt}:
899
 
 
900
 
\quotefile snippets/patternist/doc.txt
901
 
 
902
 
Suppose you want the first \c{<span>} element of every \c{<p>}
903
 
element. Apply a position filter (\c{[1]}) to the \c{/span} path step:
904
 
 
905
 
\quotefile snippets/patternist/filterOnStep.xq
906
 
 
907
 
Applying the \c{[1]} filter to the \c{/span} step returns the first
908
 
\c{<span>} element of each \c{<p>} element:
909
 
 
910
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 41
911
 
 
912
 
\note: You can write the same query this way:
913
 
 
914
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 44
915
 
 
916
 
Or you can reduce it right down to this:
917
 
 
918
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 45
919
 
 
920
 
On the other hand, suppose you really want only one \c{<span>}
921
 
element, the first one in the document (i.e., you only want the first
922
 
\c{<span>} element in the first \c{<p>} element). Then you have to do
923
 
more filtering. There are two ways you can do it. You can apply the
924
 
\c{[1]} filter in the same place as above but enclose the path
925
 
expression in parentheses:
926
 
 
927
 
\quotefile snippets/patternist/filterOnPath.xq
928
 
 
929
 
Or you can apply a second position filter (\c{[1]} again) to the
930
 
\c{/p} path step:
931
 
 
932
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 43
933
 
 
934
 
Either way the query will return only the first \c{<span>} element in
935
 
the document:
936
 
 
937
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 42
938
 
 
939
 
\section2 Why doesn't my FLWOR behave as expected?
940
 
 
941
 
The quick answer is you probably expected your XQuery FLWOR to behave
942
 
just like a C++ \e{for} loop. But they aren't the same. Consider a
943
 
simple example:
944
 
 
945
 
\quotefile snippets/patternist/letOrderBy.xq
946
 
 
947
 
This query evaluates to \e{4 -4 -2 2 -8 8}. The \e{for} clause does
948
 
set up a \e{for} loop style iteration, which does evaluate the rest of
949
 
the FLWOR multiple times, one time for each value returned by the
950
 
\e{in} expression. That much is similar to the C++ \e{for} loop.
951
 
 
952
 
But consider the \e{return} clause. In C++ if you hit a \e{return}
953
 
statement, you break out of the \e{for} loop and return from the
954
 
function with one value. Not so in XQuery. The \e{return} clause is
955
 
the last clause of the FLWOR, and it means: \e{Append the return value
956
 
to the result list and then begin the next iteration of the FLWOR}.
957
 
When the \e{for} clause's \e{in} expression no longer returns a value,
958
 
the entire result list is returned.
959
 
 
960
 
Next, consider the \e{order by} clause. It doesn't do any sorting on
961
 
each iteration of the FLWOR. It just evaluates its expression on each
962
 
iteration (\c{$a} in this case) to get an ordering value to map to the
963
 
result item from each iteration. These ordering values are kept in a
964
 
parallel list. The result list is sorted at the end using the parallel
965
 
list of ordering values.
966
 
 
967
 
The last difference to note here is that the \e{let} clause does
968
 
\e{not} set up an iteration through a sequence of values like the
969
 
\e{for} clause does. The \e{let} clause isn't a sort of nested loop.
970
 
It isn't a loop at all. It is just a variable binding.  On each
971
 
iteration, it binds the \e{entire} sequence of values on the right to
972
 
the variable on the left. In the example above, it binds (4 -4) to
973
 
\c{$b} on the first iteration, (-2 2) on the second iteration, and (-8
974
 
8) on the third iteration. So the following query doesn't iterate
975
 
through anything, and doesn't do any ordering:
976
 
 
977
 
\quotefile snippets/patternist/invalidLetOrderBy.xq
978
 
 
979
 
It binds the entire sequence (2, 3, 1) to \c{$i} one time only; the
980
 
\e{order by} clause only has one thing to order and hence does
981
 
nothing, and the query evaluates to 2 3 1, the sequence assigned to
982
 
\c{$i}.
983
 
 
984
 
\note We didn't include a \e{where} clause in the example. The
985
 
\e{where} clause is for filtering results.
986
 
 
987
 
\section2 Why are my elements created in the wrong order?
988
 
 
989
 
The short answer is your elements are \e{not} created in the wrong
990
 
order, because when appearing as operands to a path expression,
991
 
there is no correct order. Consider the following query,
992
 
which again uses the input file \c{doc.txt}:
993
 
 
994
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 46
995
 
 
996
 
The query finds all the \c{<p>} elements in the file. For each \c{<p>}
997
 
element, it builds a \c{<p>} element in the output containing the
998
 
concatenated contents of all the \c{<p>} element's child \c{<span>}
999
 
elements. Running the query through \c{xmlpatterns} might produce the
1000
 
following output, which is not sorted in the expected order.
1001
 
 
1002
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 47
1003
 
 
1004
 
You can use a \e{for} loop to ensure that the order of
1005
 
the result set corresponds to the order of the input sequence:
1006
 
 
1007
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 48
1008
 
 
1009
 
This version produces the same result set but in the expected order:
1010
 
 
1011
 
\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 49
1012
 
 
1013
 
\section2 Why can't I use \c{true} and \c{false} in my XQuery?
1014
 
 
1015
 
You can, but not by just using the names \c{true} and \c{false}
1016
 
directly, because they are \l{Name Tests} {name tests} although they look
1017
 
like boolean constants. The simple way to create the boolean values is
1018
 
to use the builtin functions \c{true()} and \c{false()} wherever
1019
 
you want to use \c{true} and \c{false}. The other way is to invoke the
1020
 
boolean constructor:
1021
 
 
1022
 
\quotefile snippets/patternist/xsBooleanTrue.xq
1023
 
 
1024
 
*/