1 | /****************************************************************************
|
---|
2 | **
|
---|
3 | ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
---|
4 | ** Contact: Qt Software Information ([email protected])
|
---|
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 [email protected].
|
---|
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 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 | */
|
---|