source: trunk/src/xmlpatterns/api/qxmlquery.cpp@ 779

Last change on this file since 779 was 651, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.2 sources.

File size: 38.9 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtXmlPatterns module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this 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 have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include <QtCore/QBuffer>
43#include <QtCore/QStringList>
44#include <QtXmlPatterns/QXmlFormatter>
45
46#include "qacceltreeresourceloader_p.h"
47#include "qcommonvalues_p.h"
48#include "qxmlresultitems.h"
49#include "qxmlresultitems_p.h"
50#include "qxmlserializer.h"
51#include "qxpathhelper_p.h"
52
53#include "qxmlquery.h"
54#include "qxmlquery_p.h"
55
56QT_BEGIN_NAMESPACE
57
58/*!
59 \class QXmlQuery
60
61 \brief The QXmlQuery class performs XQueries on XML data, or on non-XML data modeled to look like XML.
62
63 \reentrant
64 \since 4.4
65 \ingroup xml-tools
66
67 The QXmlQuery class compiles and executes queries written in the
68 \l {http://www.w3.org/TR/xquery/}{XQuery language}. QXmlQuery is
69 typically used to query XML data, but it can also query non-XML
70 data that has been modeled to look like XML.
71
72 Using QXmlQuery to query XML data, as in the snippet below, is
73 simple because it can use the built-in \l {QAbstractXmlNodeModel}
74 {XML data model} as its delegate to the underlying query engine for
75 traversing the data. The built-in data model is specified in \l
76 {http://www.w3.org/TR/xpath-datamodel/} {XQuery 1.0 and XPath 2.0
77 Data Model}.
78
79 \snippet doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlreceiver.cpp 0
80
81 The example uses QXmlQuery to match the first paragraph of an XML
82 document and then \l {QXmlSerializer} {output the result} to a
83 device as XML.
84
85 Using QXmlQuery to query \e {non-XML} data requires writing a
86 subclass of QAbstractXmlNodeModel to use as a replacement for the
87 built-in XML data model. The custom data model will be able to
88 traverse the non-XML data as required by the QAbstractXmlNodeModel
89 interface. An instance of this custom data model then becomes the
90 delegate used by the query engine to traverse the non-XML data. For
91 an example of how to use QXmlQuery to query non-XML data, see the
92 documentation for QAbstractXmlNodeModel.
93
94 \section1 Running XQueries
95
96 To run a query set up with QXmlQuery, call one of the evaluation
97 functions.
98
99 \list
100
101 \o evaluateTo(QAbstractXmlReceiver *) is called with a pointer to an
102 XML \l {QAbstractXmlReceiver} {receiver}, which receives the query
103 results as a sequence of callbacks. The receiver callback class is
104 like the callback class used for translating the output of a SAX
105 parser. QXmlSerializer, for example, is a receiver callback class
106 for translating the sequence of callbacks for output as unformatted
107 XML text.
108
109 \endlist
110
111 \list
112
113 \o evaluateTo(QXmlResultItems *) is called with a pointer to an
114 iterator for an empty sequence of query \l {QXmlResultItems} {result
115 items}. The Java-like iterator allows the query results to be
116 accessed sequentially.
117
118 \endlist
119
120 \list
121
122 \o evaluateTo(QStringList *) is like evaluateTo(QXmlResultItems *),
123 but the query must evaluate to a sequence of strings.
124
125 \endlist
126
127 \section1 Running XPath Expressions
128
129 The XPath language is a subset of the XQuery language, so
130 running an XPath expression is the same as running an XQuery
131 query. Pass the XPath expression to QXmlQuery using setQuery().
132
133 \section1 Running XSLT stylesheets
134
135 Running an XSLT stylesheet is like running an XQuery, except that
136 when you construct your QXmlQuery, you must pass QXmlQuery::XSLT20
137 to tell QXmlQuery to interpret whatever it gets from setQuery() as
138 an XSLT stylesheet instead of as an XQuery. You must also set the
139 input document by calling setFocus().
140
141 \snippet doc/src/snippets/code/src_xmlpatterns_api_qxmlquery.cpp 7
142
143 \note Currently, setFocus() must be called \e before setQuery() when
144 using XSLT.
145
146 Another way to run an XSLT stylesheet is to use the \c xmlpatterns
147 command line utility.
148
149 \code
150 xmlpatterns myStylesheet.xsl myInput.xml
151 \endcode
152
153 \note For the current release, XSLT support should be considered
154 experimental. See section \l{Using XML technologies#XSLT
155 2.0}{XSLT conformance} for details.
156
157 Stylesheet parameters are bound using bindVariable().
158
159 \section1 Binding A Query To A Starting Node
160
161 When a query is run on XML data, as in the snippet above, the
162 \c{doc()} function returns the node in the built-in data model where
163 the query evaluation will begin. But when a query is run on a custom
164 node model containing non-XML data, one of the bindVariable()
165 functions must be called to bind a variable name to a starting node
166 in the custom model. A $variable reference is used in the XQuery
167 text to access the starting node in the custom model. It is not
168 necessary to declare the variable name external in the query. See
169 the example in the documentation for QAbstractXmlNodeModel.
170
171 \section1 Reentrancy and Thread-Safety
172
173 QXmlQuery is reentrant but not thread-safe. It is safe to use the
174 QxmlQuery copy constructor to create a copy of a query and run the
175 same query multiple times. Behind the scenes, QXmlQuery will reuse
176 resources such as opened files and compiled queries to the extent
177 possible. But it is not safe to use the same instance of QXmlQuery
178 in multiple threads.
179
180 \section1 Error Handling
181
182 Errors can occur during query evaluation. Examples include type
183 errors and file loading errors. When an error occurs:
184
185 \list
186
187 \o The error message is sent to the messageHandler().
188
189 \o QXmlResultItems::hasError() will return \c{true}, or
190 evaluateTo() will return \c{false};
191
192 \o The results of the evaluation are undefined.
193
194 \endlist
195
196 \section1 Resource Management
197
198 When a query runs, it parses documents, allocating internal data
199 structures to hold them, and it may load other resources over the
200 network. It reuses these allocated resources when possible, to
201 avoid having to reload and reparse them.
202
203 When setQuery() is called, the query text is compiled into an
204 internal data structure and optimized. The optimized form can
205 then be reused for multiple evaluations of the query. Since the
206 compile-and-optimize process can be expensive, repeating it for
207 the same query should be avoided by using a separate instance of
208 QXmlQuery for each query text.
209
210 Once a document has been parsed, its internal representation is
211 maintained in the QXmlQuery instance and shared among multiple
212 QXmlQuery instances.
213
214 An instance of QCoreApplication must exist before QXmlQuery can be
215 used.
216
217 \section1 Event Handling
218
219 When QXmlQuery accesses resources (e.g., calling \c fn:doc() to load a file,
220 or accessing a device via a bound variable), the event loop is used, which
221 means events will be processed. To avoid processing events when QXmlQuery
222 accesses resources, create your QXmlQuery instance in a separate thread.
223 */
224
225/*!
226 \enum QXmlQuery::QueryLanguage
227 \since 4.5
228
229 Specifies whether you want QXmlQuery to interpret the input to
230 setQuery() as an XQuery or as an XSLT stylesheet.
231
232 \value XQuery10 XQuery 1.0.
233 \value XSLT20 XSLT 2.0
234 \omitvalue XmlSchema11IdentityConstraintSelector The selector, the restricted
235 XPath pattern found in W3C XML Schema 1.1 for uniqueness
236 contraints. Apart from restricting the syntax, the type check stage
237 for the expression assumes a sequence of nodes to be the focus.
238 \omitvalue XmlSchema11IdentityConstraintField The field, the restricted
239 XPath pattern found in W3C XML Schema 1.1 for uniqueness
240 contraints. Apart from restricting the syntax, the type check stage
241 for the expression assumes a sequence of nodes to be the focus.
242 \omitvalue XPath20 Signifies XPath 2.0. Has no effect in the public API, it's
243 used internally. As With XmlSchema11IdentityConstraintSelector and
244 XmlSchema11IdentityConstraintField, the type check stage
245 for the expression assumes a sequence of nodes to be the focus.
246
247 \sa setQuery()
248 */
249
250// ### Qt5: Merge constructor overloads
251/*!
252 Constructs an invalid, empty query that cannot be used until
253 setQuery() is called.
254
255 \note This constructor must not be used if you intend to use
256 this QXmlQuery to process XSL-T stylesheets. The other constructor
257 must be used in that case.
258 */
259QXmlQuery::QXmlQuery() : d(new QXmlQueryPrivate())
260{
261}
262
263/*!
264 Constructs a QXmlQuery that is a copy of \a other. The new
265 instance will share resources with the existing query
266 to the extent possible.
267 */
268QXmlQuery::QXmlQuery(const QXmlQuery &other) : d(new QXmlQueryPrivate(*other.d))
269{
270 /* First we have invoked QXmlQueryPrivate's synthesized copy constructor.
271 * Keep this section in sync with QXmlQuery::operator=(). */
272 d->detach();
273}
274
275/*!
276 Constructs a query that will use \a np as its name pool. The query
277 cannot be evaluated until setQuery() has been called.
278 */
279QXmlQuery::QXmlQuery(const QXmlNamePool &np) : d(new QXmlQueryPrivate(np))
280{
281}
282
283/*!
284
285 Constructs a query that will be used to run Xqueries or XSL-T
286 stylesheets, depending on the value of \a queryLanguage. It will use
287 \a np as its name pool.
288
289 \note If your QXmlQuery will process XSL-T stylesheets, this
290 constructor must be used. The default constructor can only
291 create instances of QXmlQuery for running XQueries.
292
293 \note The XSL-T support in this release is considered experimental.
294 See the \l{Using XML technologies#XSLT 2.0}{XSLT conformance} for
295 details.
296
297 \since 4.5
298 \sa queryLanguage()
299 */
300QXmlQuery::QXmlQuery(QueryLanguage queryLanguage,
301 const QXmlNamePool &np) : d(new QXmlQueryPrivate(np))
302{
303 d->queryLanguage = queryLanguage;
304}
305
306/*!
307 Destroys this QXmlQuery.
308 */
309QXmlQuery::~QXmlQuery()
310{
311 delete d;
312}
313
314/*!
315 Assigns \a other to this QXmlQuery instance.
316 */
317QXmlQuery &QXmlQuery::operator=(const QXmlQuery &other)
318{
319 /* Keep this section in sync with QXmlQuery::QXmlQuery(const QXmlQuery &).
320 */
321 if(d != other.d)
322 {
323 *d = *other.d;
324 d->detach();
325 }
326
327 return *this;
328}
329
330/*!
331 Changes the \l {QAbstractMessageHandler}{message handler} for this
332 QXmlQuery to \a aMessageHandler. The query sends all compile and
333 runtime messages to this message handler. QXmlQuery does not take
334 ownership of \a aMessageHandler.
335
336 Normally, the default message handler is sufficient. It writes
337 compile and runtime messages to \e stderr. The default message
338 handler includes color codes if \e stderr can render colors.
339
340 Note that changing the message handler after the query has been
341 compiled has no effect, i.e. the query uses the same message handler
342 at runtime that it uses at compile time.
343
344 When QXmlQuery calls QAbstractMessageHandler::message(),
345 the arguments are as follows:
346
347 \table
348 \header
349 \o message() argument
350 \o Semantics
351 \row
352 \o QtMsgType type
353 \o Only QtWarningMsg and QtFatalMsg are used. The former
354 identifies a compile or runtime warning, while the
355 latter identifies a dynamic or static error.
356 \row
357 \o const QString & description
358 \o An XHTML document which is the actual message. It is translated
359 into the current language.
360 \row
361 \o const QUrl &identifier
362 \o Identifies the error with a URI, where the fragment is
363 the error code, and the rest of the URI is the error namespace.
364 \row
365 \o const QSourceLocation & sourceLocation
366 \o Identifies where the error occurred.
367 \endtable
368
369 */
370void QXmlQuery::setMessageHandler(QAbstractMessageHandler *aMessageHandler)
371{
372 d->messageHandler = aMessageHandler;
373}
374
375/*!
376 Returns the message handler that handles compile and runtime
377 messages for this QXmlQuery.
378 */
379QAbstractMessageHandler *QXmlQuery::messageHandler() const
380{
381 return d->messageHandler;
382}
383
384/*!
385 Sets this QXmlQuery to an XQuery read from the \a sourceCode
386 device. The device must have been opened with at least
387 QIODevice::ReadOnly.
388
389 \a documentURI represents the query obtained from the \a sourceCode
390 device. It is the base URI of the static context, as defined in the
391 \l {http://www.w3.org/TR/xquery/}{XQuery language}. It is used
392 internally to resolve relative URIs that appear in the query, and
393 for message reporting. \a documentURI can be empty. If it is empty,
394 the \l{QCoreApplication::applicationFilePath()} {application file
395 path} is used. If it is not empty, it may be either relative or
396 absolute. If it is relative, it is resolved itself against the
397 \l {QCoreApplication::applicationFilePath()} {application file
398 path} before it is used. If \a documentURI is neither a valid URI
399 nor empty, the result is undefined.
400
401 If the query contains a static error (e.g. syntax error), an error
402 message is sent to the messageHandler(), and isValid() will return
403 \e false.
404
405 Variables must be bound before setQuery() is called.
406
407 The encoding of the XQuery in \a sourceCode is detected internally
408 using the rules for setting and detecting encoding of XQuery files,
409 which are explained in the \l {http://www.w3.org/TR/xquery/}
410 {XQuery language}.
411
412 If \a sourceCode is \c null or not readable, or if \a documentURI is not
413 a valid URI, behavior is undefined.
414 \sa isValid()
415 */
416void QXmlQuery::setQuery(QIODevice *sourceCode, const QUrl &documentURI)
417{
418 if(!sourceCode)
419 {
420 qWarning("A null QIODevice pointer cannot be passed.");
421 return;
422 }
423
424 if(!sourceCode->isReadable())
425 {
426 qWarning("The device must be readable.");
427 return;
428 }
429
430 d->queryURI = QPatternist::XPathHelper::normalizeQueryURI(documentURI);
431 d->expression(sourceCode);
432}
433
434/*!
435 \overload
436 The behavior and requirements of this function are the same as for
437 setQuery(QIODevice*, const QUrl&), after the XQuery has been read
438 from the IO device into a string. Because \a sourceCode is already
439 a Unicode string, detection of its encoding is unnecessary.
440*/
441void QXmlQuery::setQuery(const QString &sourceCode, const QUrl &documentURI)
442{
443 Q_ASSERT_X(documentURI.isEmpty() || documentURI.isValid(), Q_FUNC_INFO,
444 "The document URI must be valid.");
445
446 QByteArray query(sourceCode.toUtf8());
447 QBuffer buffer(&query);
448 buffer.open(QIODevice::ReadOnly);
449
450 setQuery(&buffer, documentURI);
451}
452
453/*!
454 Sets this QXmlQuery to the XQuery read from the \a queryURI. Use
455 isValid() after calling this function. If an error occurred reading
456 \a queryURI, e.g., the query does not exist, cannot be read, or is
457 invalid, isValid() will return \e false.
458
459 The supported URI schemes are the same as those in the XQuery
460 function \c{fn:doc}, except that queryURI can be the object of
461 a variable binding.
462
463 \a baseURI is the Base URI of the static context, as defined in the
464 \l {http://www.w3.org/TR/xquery/}{XQuery language}. It is used
465 internally to resolve relative URIs that appear in the query, and
466 for message reporting. If \a baseURI is empty, \a queryURI is used.
467 Otherwise, \a baseURI is used, and it is resolved against the \l
468 {QCoreApplication::applicationFilePath()} {application file path} if
469 it is relative.
470
471 If \a queryURI is empty or invalid, or if \a baseURI is invalid,
472 the behavior of this function is undefined.
473 */
474void QXmlQuery::setQuery(const QUrl &queryURI, const QUrl &baseURI)
475{
476 Q_ASSERT_X(queryURI.isValid(), Q_FUNC_INFO, "The passed URI must be valid.");
477
478 const QUrl canonicalURI(QPatternist::XPathHelper::normalizeQueryURI(queryURI));
479 Q_ASSERT(canonicalURI.isValid());
480 Q_ASSERT(!canonicalURI.isRelative());
481 Q_ASSERT(baseURI.isValid() || baseURI.isEmpty());
482
483 d->queryURI = QPatternist::XPathHelper::normalizeQueryURI(baseURI.isEmpty() ? queryURI : baseURI);
484
485 QPatternist::AutoPtr<QIODevice> result;
486
487 try
488 {
489 result.reset(QPatternist::AccelTreeResourceLoader::load(canonicalURI, d->m_networkAccessDelegator,
490 d->staticContext()));
491 }
492 catch(const QPatternist::Exception)
493 {
494 /* We do nothing, result will be 0. */
495 }
496
497 if(result)
498 {
499 setQuery(result.data(), d->queryURI);
500 result->close();
501 }
502 else
503 d->recompileRequired();
504}
505
506/*!
507 Binds the variable \a name to the \a value so that $\a name can be
508 used from within the query to refer to the \a value.
509
510 \a name must not be \e null. \a {name}.isNull() must return false.
511 If \a name has already been bound by a previous bindVariable() call,
512 its previous binding will be overridden.
513
514 If \a {value} is null so that \a {value}.isNull() returns true, and
515 \a {name} already has a binding, the effect is to remove the
516 existing binding for \a {name}.
517
518 To bind a value of type QString or QUrl, wrap the value in a
519 QVariant such that QXmlItem's QVariant constructor is called.
520
521 All strings processed by the query must be valid XQuery strings,
522 which means they must contain only XML 1.0 characters. However,
523 this requirement is not checked. If the query processes an invalid
524 string, the behavior is undefined.
525
526 \sa QVariant::isValid(), {QtXDM}{How QVariant maps to XQuery's Data Model},
527 QXmlItem::isNull()
528 */
529void QXmlQuery::bindVariable(const QXmlName &name, const QXmlItem &value)
530{
531 if(name.isNull())
532 {
533 qWarning("The variable name cannot be null.");
534 return;
535 }
536
537 const QPatternist::VariableLoader::Ptr vl(d->variableLoader());
538 const QVariant variant(qVariantFromValue(value));
539
540 /* If the type of the variable changed(as opposed to only the value),
541 * we will have to recompile. */
542 if(vl->invalidationRequired(name, variant) || value.isNull())
543 d->recompileRequired();
544
545 vl->addBinding(name, variant);
546}
547
548/*!
549 \overload
550
551 This function constructs a QXmlName from \a localName using the
552 query's \l {QXmlNamePool} {namespace}. The function then behaves as
553 the overloaded function. It is equivalent to the following snippet.
554
555 \snippet doc/src/snippets/code/src_xmlpatterns_api_qxmlquery.cpp 0
556 */
557void QXmlQuery::bindVariable(const QString &localName, const QXmlItem &value)
558{
559 bindVariable(QXmlName(d->namePool, localName), value);
560}
561
562/*!
563 Binds the variable \a name to the \a device so that $\a name can be
564 used from within the query to refer to the \a device. The QIODevice
565 \a device is exposed to the query as a URI of type \c{xs:anyURI},
566 which can be passed to the \c{fn:doc()} function to be read. E.g.,
567 this function can be used to pass an XML document in memory to
568 \c{fn:doc}.
569
570 \snippet doc/src/snippets/code/src_xmlpatterns_api_qxmlquery.cpp 1
571
572 The caller must ensure that \a device has been opened with at least
573 QIODevice::ReadOnly prior to this binding. Otherwise, behavior is
574 undefined.
575
576 If the query will access an XML document contained in a QString, use
577 a QBuffer as shown in the following snippet. Suppose \e myQString
578 contains \c{<document>content</document>}
579
580 \snippet doc/src/snippets/qxmlquery/bindingExample.cpp 0
581
582 \a name must not be \e null. \a {name}.isNull() must return false.
583 If \a name has already been bound, its previous binding will be
584 overridden. The URI that \a name evaluates to is arbitrary and may
585 change.
586
587 If the type of the variable binding changes (e.g., if a previous
588 binding by the same name was a QVariant, or if there was no previous
589 binding), isValid() will return \c{false}, and recompilation of the
590 query text is required. To recompile the query, call setQuery(). For
591 this reason, bindVariable() should be called before setQuery(), if
592 possible.
593
594 \note \a device must not be deleted while this QXmlQuery exists.
595*/
596void QXmlQuery::bindVariable(const QXmlName &name, QIODevice *device)
597{
598 if(device && !device->isReadable())
599 {
600 qWarning("A null, or readable QIODevice must be passed.");
601 return;
602 }
603
604 if(name.isNull())
605 {
606 qWarning("The variable name cannot be null.");
607 return;
608 }
609
610 const QPatternist::VariableLoader::Ptr vl(d->variableLoader());
611
612 if(device)
613 {
614 const QVariant variant(qVariantFromValue(device));
615
616 if(vl->invalidationRequired(name, variant))
617 d->recompileRequired();
618
619 vl->addBinding(name, variant);
620
621 /* We need to tell the resource loader to discard its document, because
622 * the underlying QIODevice has changed, but the variable name is the
623 * same which means that the URI is the same, and hence the resource
624 * loader will return the document for the old QIODevice.
625 */
626 d->resourceLoader()->clear(QUrl(QLatin1String("tag:trolltech.com,2007:QtXmlPatterns:QIODeviceVariable:") + d->namePool.d->stringForLocalName(name.localName())));
627 }
628 else
629 {
630 vl->removeBinding(name);
631 d->recompileRequired();
632 }
633}
634
635/*!
636 \overload
637
638 If \a localName is a valid \l {QXmlName::isNCName()} {NCName}, this
639 function is equivalent to the following snippet.
640
641 \snippet doc/src/snippets/code/src_xmlpatterns_api_qxmlquery.cpp 2
642
643 A QXmlName is constructed from \a localName, and is passed
644 to the appropriate overload along with \a device.
645
646 \sa QXmlName::isNCName()
647 */
648void QXmlQuery::bindVariable(const QString &localName, QIODevice *device)
649{
650 bindVariable(QXmlName(d->namePool, localName), device);
651}
652
653/*!
654 Evaluates this query and sends the result as a sequence of callbacks
655 to the \l {QAbstractXmlReceiver} {receiver} \a callback. QXmlQuery
656 does not take ownership of \a callback.
657
658 If an error occurs during the evaluation, error messages are sent to
659 messageHandler() and \c false is returned.
660
661 If this query \l {isValid()} {is invalid}, \c{false} is returned
662 and the behavior is undefined. If \a callback is null,
663 behavior is undefined.
664
665 \sa QAbstractXmlReceiver, isValid()
666 */
667bool QXmlQuery::evaluateTo(QAbstractXmlReceiver *callback) const
668{
669 if(!callback)
670 {
671 qWarning("A non-null callback must be passed.");
672 return false;
673 }
674
675 if(isValid())
676 {
677 try
678 {
679 /*
680 * This order is significant. expression() might cause
681 * query recompilation, and as part of that it recreates
682 * the static context. However, if we create the dynamic
683 * context before the query recompilation has been
684 * triggered, it will use the old static context, and
685 * hence old source locations.
686 */
687 const QPatternist::Expression::Ptr expr(d->expression());
688 const QPatternist::DynamicContext::Ptr dynContext(d->dynamicContext(callback));
689 callback->startOfSequence();
690 expr->evaluateToSequenceReceiver(dynContext);
691 callback->endOfSequence();
692 return true;
693 }
694 catch(const QPatternist::Exception)
695 {
696 return false;
697 }
698 }
699 else
700 return false;
701}
702
703/*!
704 Attempts to evaluate the query and returns the results in the
705 \a target \l {QStringList} {string list}.
706
707 If the query \l {isValid()} {is valid} and the evaluation succeeds,
708 true is returned. Otherwise, false is returned and the contents of
709 \a target are undefined.
710
711 The query must evaluate to a sequence of \c{xs:string} values. If
712 the query does not evaluate to a sequence of strings, the values can
713 often be converted by adding a call to \c{string()} at the end of
714 the XQuery.
715
716 If \a target is null, the behavior is undefined.
717 */
718bool QXmlQuery::evaluateTo(QStringList *target) const
719{
720 if(!target)
721 {
722 qWarning("A non-null callback must be passed.");
723 return false;
724 }
725
726 if(isValid())
727 {
728 try
729 {
730 /*
731 * This order is significant. expression() might cause
732 * query recompilation, and as part of that it recreates
733 * the static context. However, if we create the dynamic
734 * context before the query recompilation has been
735 * triggered, it will use the old static context, and
736 * hence old source locations.
737 */
738 const QPatternist::Expression::Ptr expr(d->expression());
739 if(!expr)
740 return false;
741
742 QPatternist::DynamicContext::Ptr dynContext(d->dynamicContext());
743
744 if(!QPatternist::BuiltinTypes::xsString->xdtTypeMatches(expr->staticType()->itemType()))
745 return false;
746
747 const QPatternist::Item::Iterator::Ptr it(expr->evaluateSequence(dynContext));
748 QPatternist::Item next(it->next());
749
750 while(!next.isNull())
751 {
752 target->append(next.stringValue());
753 next = it->next();
754 }
755
756 return true;
757 }
758 catch(const QPatternist::Exception)
759 {
760 return false;
761 }
762 }
763 else
764 return false;
765}
766
767/*!
768 Evaluates the query or stylesheet, and writes the output to \a target.
769
770 QXmlSerializer is used to write the output to \a target. In a future
771 release, it is expected that this function will be changed to
772 respect serialization options set in the stylesheet.
773
774 If an error occurs during the evaluation, error messages are sent to
775 messageHandler() and \c false is returned.
776
777 If \a target is \c null, or is not opened in at least
778 QIODevice::WriteOnly mode, the behavior is undefined. QXmlQuery
779 does not take ownership of \a target.
780
781 \since 4.5
782 \overload
783 */
784bool QXmlQuery::evaluateTo(QIODevice *target) const
785{
786 if(!target)
787 {
788 qWarning("The pointer to the device cannot be null.");
789 return false;
790 }
791
792 if(!target->isWritable())
793 {
794 qWarning("The device must be writable.");
795 return false;
796 }
797
798 QXmlSerializer serializer(*this, target);
799 return evaluateTo(&serializer);
800}
801
802/*!
803 Starts the evaluation and makes it available in \a result. If \a
804 result is null, the behavior is undefined. The evaluation takes
805 place incrementally (lazy evaluation), as the caller uses
806 QXmlResultItems::next() to get the next result.
807
808 \sa QXmlResultItems::next()
809*/
810void QXmlQuery::evaluateTo(QXmlResultItems *result) const
811{
812 if(!result)
813 {
814 qWarning("A null pointer cannot be passed.");
815 return;
816 }
817
818 if(isValid())
819 {
820 try
821 {
822 /*
823 * We don't have the d->expression() calls and
824 * d->dynamicContext() calls in the same order as seen in
825 * QXmlQuery::evaluateTo(), and the reason to why
826 * that isn't a problem, is that we call isValid().
827 */
828 const QPatternist::DynamicContext::Ptr dynContext(d->dynamicContext());
829 result->d_ptr->setDynamicContext(dynContext);
830 result->d_ptr->iterator = d->expression()->evaluateSequence(dynContext);
831 }
832 catch(const QPatternist::Exception)
833 {
834 result->d_ptr->iterator = QPatternist::CommonValues::emptyIterator;
835 result->d_ptr->hasError = true;
836 }
837 }
838 else
839 {
840 result->d_ptr->iterator= QPatternist::CommonValues::emptyIterator;
841 result->d_ptr->hasError = true;
842 }
843}
844
845/*!
846 Evaluates the query, and serializes the output as XML to \a output.
847
848 If an error occurs during the evaluation, error messages are sent to
849 messageHandler(), the content of \a output is undefined and \c false is
850 returned, otherwise \c true is returned.
851
852 If \a output is \c null behavior is undefined. QXmlQuery
853 does not take ownership of \a output.
854
855 Internally, the class QXmlFormatter is used for this.
856 \since 4.5
857 */
858bool QXmlQuery::evaluateTo(QString *output) const
859{
860 Q_ASSERT_X(output, Q_FUNC_INFO,
861 "The input cannot be null");
862
863 QBuffer outputDevice;
864 outputDevice.open(QIODevice::ReadWrite);
865
866 QXmlFormatter formatter(*this, &outputDevice);
867 const bool success = evaluateTo(&formatter);
868
869 outputDevice.close();
870 *output = QString::fromUtf8(outputDevice.data().constData());
871
872 return success;
873}
874
875/*!
876 Returns true if this query is valid. Examples of invalid queries
877 are ones that contain syntax errors or that have not had setQuery()
878 called for them yet.
879 */
880bool QXmlQuery::isValid() const
881{
882 return d->isValid();
883}
884
885/*!
886 Sets the URI resolver to \a resolver. QXmlQuery does not take
887 ownership of \a resolver.
888
889 \sa uriResolver()
890 */
891void QXmlQuery::setUriResolver(const QAbstractUriResolver *resolver)
892{
893 d->uriResolver = resolver;
894}
895
896/*!
897 Returns the query's URI resolver. If no URI resolver has been set,
898 QtXmlPatterns will use the URIs in queries as they are.
899
900 The URI resolver provides a level of abstraction, or \e{polymorphic
901 URIs}. A resolver can rewrite \e{logical} URIs to physical ones, or
902 it can translate obsolete or invalid URIs to valid ones.
903
904 QtXmlPatterns calls the URI resolver for all URIs it encounters,
905 except for namespaces. Specifically, all builtin functions that deal
906 with URIs (\c{fn:doc()}, and \c{fn:doc-available()}).
907
908 In the case of \c{fn:doc()}, the absolute URI is the base URI in the
909 static context (which most likely is the location of the query).
910 Rather than use the URI the user specified, the return value of
911 QAbstractUriResolver::resolve() will be used.
912
913 When QtXmlPatterns calls QAbstractUriResolver::resolve() the
914 absolute URI is the URI mandated by the XQuery language, and the
915 relative URI is the URI specified by the user.
916
917 \sa setUriResolver()
918 */
919const QAbstractUriResolver *QXmlQuery::uriResolver() const
920{
921 return d->uriResolver;
922}
923
924/*!
925 Returns the name pool used by this QXmlQuery for constructing \l
926 {QXmlName} {names}. There is no setter for the name pool, because
927 mixing name pools causes errors due to name confusion.
928 */
929QXmlNamePool QXmlQuery::namePool() const
930{
931 return d->namePool;
932}
933
934/*!
935 Sets the focus to \a item. The focus is the set of items that the
936 context item expression and path expressions navigate from. For
937 example, in the expression \e p/span, the element that \e p
938 evaluates to is the focus for the following expression, \e span.
939
940 The focus can be accessed using the context item expression, i.e.,
941 dot (".").
942
943 By default, the focus is not set and is undefined. It will
944 therefore result in a dynamic error, \c XPDY0002, if the focus
945 is attempted to be accessed. The focus must be set before the
946 query is set with setQuery().
947
948 There is no behavior defined for setting an item which is null.
949
950 */
951void QXmlQuery::setFocus(const QXmlItem &item)
952{
953 d->contextItem = item;
954}
955
956/**
957 * This function should be a private member function of QXmlQuery,
958 * but we don't dare that due to our weird compilers.
959 * @internal
960 * @relates QXmlQuery
961 */
962template<typename TInputType>
963bool setFocusHelper(QXmlQuery *const queryInstance,
964 const TInputType &focusValue)
965{
966 /* We call resourceLoader(), so we have ensured that we have a resourceLoader
967 * that we will share in our copy. */
968 queryInstance->d->resourceLoader();
969
970 QXmlQuery focusQuery(*queryInstance);
971
972 /* Now we use the same, so we own the loaded document. */
973 focusQuery.d->m_resourceLoader = queryInstance->d->m_resourceLoader;
974
975 /* The copy constructor doesn't allow us to copy an existing QXmlQuery and
976 * changing the language at the same time so we need to use private API. */
977 focusQuery.d->queryLanguage = QXmlQuery::XQuery10;
978
979 Q_ASSERT(focusQuery.queryLanguage() == QXmlQuery::XQuery10);
980 focusQuery.bindVariable(QChar::fromLatin1('u'), focusValue);
981 focusQuery.setQuery(QLatin1String("doc($u)"));
982 Q_ASSERT(focusQuery.isValid());
983
984 QXmlResultItems focusResult;
985
986 queryInstance->d->m_resourceLoader = focusQuery.d->m_resourceLoader;
987
988 focusQuery.evaluateTo(&focusResult);
989 const QXmlItem focusItem(focusResult.next());
990
991 if(focusItem.isNull() || focusResult.hasError())
992 return false;
993 else
994 {
995 queryInstance->setFocus(focusItem);
996 return true;
997 }
998}
999
1000/*!
1001 \since 4.5
1002 \overload
1003
1004 Sets the focus to be the document located at \a documentURI and
1005 returns true. If \a documentURI cannot be loaded, false is returned.
1006 It is undefined at what time the document may be loaded. When
1007 loading the document, the message handler and URI resolver set on
1008 this QXmlQuery are used.
1009
1010 If \a documentURI is empty or is not a valid URI, the behavior of
1011 this function is undefined.
1012 */
1013bool QXmlQuery::setFocus(const QUrl &documentURI)
1014{
1015 Q_ASSERT_X(documentURI.isValid() && !documentURI.isEmpty(),
1016 Q_FUNC_INFO,
1017 "The URI passed must be valid.");
1018
1019 return setFocusHelper(this, QVariant(documentURI));
1020}
1021
1022/*!
1023
1024 Sets the focus to be the \a document read from the QIODevice and
1025 returns true. If \a document cannot be loaded, false is returned.
1026
1027 QXmlQuery does not take ownership of \a document. The user
1028 guarantees that a document is available from the \a document device
1029 and that the document is not empty. The device must be opened in at
1030 least read-only mode. \a document must stay in scope as long as the
1031 current query is active.
1032
1033 \since 4.5
1034 \overload
1035 */
1036bool QXmlQuery::setFocus(QIODevice *document)
1037{
1038 if(!document)
1039 {
1040 qWarning("A null QIODevice pointer cannot be passed.");
1041 return false;
1042 }
1043
1044 if(!document->isReadable())
1045 {
1046 qWarning("The device must be readable.");
1047 return false;
1048 }
1049
1050 return setFocusHelper(this, document);
1051}
1052
1053/*!
1054 This function behaves identically to calling the setFocus() overload with a
1055 QIODevice whose content is \a focus encoded as UTF-8. That is, \a focus is
1056 treated as if it contained an XML document.
1057
1058 Returns the same result as the overload.
1059
1060 \overload
1061 \since 4.6
1062 */
1063bool QXmlQuery::setFocus(const QString &focus)
1064{
1065 QBuffer device;
1066 device.setData(focus.toUtf8());
1067 device.open(QIODevice::ReadOnly);
1068
1069 return setFocusHelper(this, &device);
1070}
1071
1072/*!
1073 Returns a value indicating what this QXmlQuery is being used for.
1074 The default is QXmlQuery::XQuery10, which means the QXmlQuery is
1075 being used for running XQuery and XPath queries. QXmlQuery::XSLT20
1076 can also be returned, which indicates the QXmlQuery is for running
1077 XSL-T spreadsheets.
1078
1079 \since 4.5
1080 */
1081QXmlQuery::QueryLanguage QXmlQuery::queryLanguage() const
1082{
1083 return d->queryLanguage;
1084}
1085
1086/*!
1087 Sets the \a name of the initial template. The initial template is
1088 the one the processor calls first, instead of attempting to match a
1089 template to the context node (if any). If an initial template is not
1090 set, the standard order of template invocation will be used.
1091
1092 This function only applies when using QXmlQuery to process XSL-T
1093 stylesheets. The name becomes part of the compiled stylesheet.
1094 Therefore, this function must be called before calling setQuery().
1095
1096 If the stylesheet has no template named \a name, the processor will
1097 use the standard order of template invocation.
1098
1099 \since 4.5
1100 \sa initialTemplateName()
1101 */
1102void QXmlQuery::setInitialTemplateName(const QXmlName &name)
1103{
1104 d->initialTemplateName = name;
1105}
1106
1107/*!
1108 \overload
1109
1110 Sets the name of the initial template to \a localName, which must be
1111 a valid \l{QXmlName::localName()} {local name}. The initial template
1112 is the one the processor calls first, instead of attempting to match
1113 a template to the context node (if any). If an initial template is
1114 not set, the standard order of template invocation will be used.
1115
1116 This function only applies when using QXmlQuery to process XSL-T
1117 stylesheets. The name becomes part of the compiled stylesheet.
1118 Therefore, this function must be called before calling setQuery().
1119
1120 If \a localName is not a valid \l{QXmlName::localName()} {local
1121 name}, the effect is undefined. If the stylesheet has no template
1122 named \a localName, the processor will use the standard order of
1123 template invocation.
1124
1125 \since 4.5
1126 \sa initialTemplateName()
1127 */
1128void QXmlQuery::setInitialTemplateName(const QString &localName)
1129{
1130 Q_ASSERT_X(QXmlName::isNCName(localName),
1131 Q_FUNC_INFO,
1132 "The name passed must be a valid NCName.");
1133 setInitialTemplateName(QXmlName(d->namePool, localName));
1134}
1135
1136/*!
1137 Returns the name of the XSL-T stylesheet template that the processor
1138 will call first when running an XSL-T stylesheet. This function only
1139 applies when using QXmlQuery to process XSL-T stylesheets. By
1140 default, no initial template is set. In that case, a default
1141 constructed QXmlName is returned.
1142
1143 \since 4.5
1144 */
1145QXmlName QXmlQuery::initialTemplateName() const
1146{
1147 return d->initialTemplateName;
1148}
1149
1150/*!
1151 Sets the network manager to \a newManager.
1152 QXmlQuery does not take ownership of \a newManager.
1153
1154 \sa networkAccessManager()
1155 \since 4.5
1156 */
1157void QXmlQuery::setNetworkAccessManager(QNetworkAccessManager *newManager)
1158{
1159 d->m_networkAccessDelegator->m_genericManager = newManager;
1160}
1161
1162/*!
1163 Returns the network manager, or 0 if it has not been set.
1164
1165 \sa setNetworkAccessManager()
1166 \since 4.5
1167 */
1168QNetworkAccessManager *QXmlQuery::networkAccessManager() const
1169{
1170 return d->m_networkAccessDelegator->m_genericManager;
1171}
1172
1173/*!
1174 Binds the result of the query \a query, to a variable by name \a name.
1175
1176 Evaluation of \a query will be commenced when this function is called.
1177
1178 If \a query is invalid, behavior is undefined. \a query will be copied.
1179
1180 \since 4.5
1181 \sa isValid()
1182 */
1183void QXmlQuery::bindVariable(const QXmlName &name, const QXmlQuery &query)
1184{
1185 Q_ASSERT_X(query.isValid(), Q_FUNC_INFO, "The query being bound must be valid.");
1186
1187 const QPatternist::VariableLoader::Ptr vl(d->variableLoader());
1188 const QVariant variant(qVariantFromValue(query));
1189
1190 if(vl->invalidationRequired(name, variant))
1191 d->recompileRequired();
1192
1193 vl->addBinding(name, variant);
1194}
1195
1196/*!
1197 \overload
1198
1199 Has the same behavior and effects as the function being overloaded, but takes
1200 the variable name \a localName as a QString. \a query is used as in the
1201 overloaded function.
1202
1203 \since 4.5
1204 */
1205void QXmlQuery::bindVariable(const QString &localName, const QXmlQuery &query)
1206{
1207 return bindVariable(QXmlName(d->namePool, localName), query);
1208}
1209
1210QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.