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

Last change on this file since 168 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 37.5 KB
Line 
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 QtXmlPatterns module 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#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{QtXmlPatterns Module#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
235 \sa setQuery()
236 */
237
238// ### Qt5: Merge constructor overloads
239/*!
240 Constructs an invalid, empty query that cannot be used until
241 setQuery() is called.
242
243 \note This constructor must not be used if you intend to use
244 this QXmlQuery to process XSL-T stylesheets. The other constructor
245 must be used in that case.
246 */
247QXmlQuery::QXmlQuery() : d(new QXmlQueryPrivate())
248{
249}
250
251/*!
252 Constructs a QXmlQuery that is a copy of \a other. The new
253 instance will share resources with the existing query
254 to the extent possible.
255 */
256QXmlQuery::QXmlQuery(const QXmlQuery &other) : d(new QXmlQueryPrivate(*other.d))
257{
258 /* First we have invoked QXmlQueryPrivate's synthesized copy constructor.
259 * Keep this section in sync with QXmlQuery::operator=(). */
260 d->detach();
261}
262
263/*!
264 Constructs a query that will use \a np as its name pool. The query
265 cannot be evaluated until setQuery() has been called.
266 */
267QXmlQuery::QXmlQuery(const QXmlNamePool &np) : d(new QXmlQueryPrivate(np))
268{
269}
270
271/*!
272
273 Constructs a query that will be used to run Xqueries or XSL-T
274 stylesheets, depending on the value of \a queryLanguage. It will use
275 \a np as its name pool.
276
277 \note If your QXmlQuery will process XSL-T stylesheets, this
278 constructor must be used. The default constructor can only
279 create instances of QXmlQuery for running XQueries.
280
281 \note The XSL-T support in this release is considered experimental.
282 See the \l{QtXmlPatterns Module#XSLT 2.0}{XSLT conformance} for
283 details.
284
285 \since 4.5
286 \sa queryLanguage()
287 */
288QXmlQuery::QXmlQuery(QueryLanguage queryLanguage,
289 const QXmlNamePool &np) : d(new QXmlQueryPrivate(np))
290{
291 d->queryLanguage = queryLanguage;
292}
293
294/*!
295 Destroys this QXmlQuery.
296 */
297QXmlQuery::~QXmlQuery()
298{
299 delete d;
300}
301
302/*!
303 Assigns \a other to this QXmlQuery instance.
304 */
305QXmlQuery &QXmlQuery::operator=(const QXmlQuery &other)
306{
307 /* Keep this section in sync with QXmlQuery::QXmlQuery(const QXmlQuery &).
308 */
309 if(d != other.d)
310 {
311 *d = *other.d;
312 d->detach();
313 }
314
315 return *this;
316}
317
318/*!
319 Changes the \l {QAbstractMessageHandler}{message handler} for this
320 QXmlQuery to \a aMessageHandler. The query sends all compile and
321 runtime messages to this message handler. QXmlQuery does not take
322 ownership of \a aMessageHandler.
323
324 Normally, the default message handler is sufficient. It writes
325 compile and runtime messages to \e stderr. The default message
326 handler includes color codes if \e stderr can render colors.
327
328 Note that changing the message handler after the query has been
329 compiled has no effect, i.e. the query uses the same message handler
330 at runtime that it uses at compile time.
331
332 When QXmlQuery calls QAbstractMessageHandler::message(),
333 the arguments are as follows:
334
335 \table
336 \header
337 \o message() argument
338 \o Semantics
339 \row
340 \o QtMsgType type
341 \o Only QtWarningMsg and QtFatalMsg are used. The former
342 identifies a compile or runtime warning, while the
343 latter identifies a dynamic or static error.
344 \row
345 \o const QString & description
346 \o An XHTML document which is the actual message. It is translated
347 into the current language.
348 \row
349 \o const QUrl &identifier
350 \o Identifies the error with a URI, where the fragment is
351 the error code, and the rest of the URI is the error namespace.
352 \row
353 \o const QSourceLocation & sourceLocation
354 \o Identifies where the error occurred.
355 \endtable
356
357 */
358void QXmlQuery::setMessageHandler(QAbstractMessageHandler *aMessageHandler)
359{
360 d->messageHandler = aMessageHandler;
361}
362
363/*!
364 Returns the message handler that handles compile and runtime
365 messages for this QXmlQuery.
366 */
367QAbstractMessageHandler *QXmlQuery::messageHandler() const
368{
369 return d->messageHandler;
370}
371
372/*!
373 Sets this QXmlQuery to an XQuery read from the \a sourceCode
374 device. The device must have been opened with at least
375 QIODevice::ReadOnly.
376
377 \a documentURI represents the query obtained from the \a sourceCode
378 device. It is the base URI of the static context, as defined in the
379 \l {http://www.w3.org/TR/xquery/}{XQuery language}. It is used
380 internally to resolve relative URIs that appear in the query, and
381 for message reporting. \a documentURI can be empty. If it is empty,
382 the \l{QCoreApplication::applicationFilePath()} {application file
383 path} is used. If it is not empty, it may be either relative or
384 absolute. If it is relative, it is resolved itself against the
385 \l {QCoreApplication::applicationFilePath()} {application file
386 path} before it is used. If \a documentURI is neither a valid URI
387 nor empty, the result is undefined.
388
389 If the query contains a static error (e.g. syntax error), an error
390 message is sent to the messageHandler(), and isValid() will return
391 \e false.
392
393 Variables must be bound before setQuery() is called.
394
395 The encoding of the XQuery in \a sourceCode is detected internally
396 using the rules for setting and detecting encoding of XQuery files,
397 which are explained in the \l {http://www.w3.org/TR/xquery/}
398 {XQuery language}.
399
400 If \a sourceCode is \c null or not readable, or if \a documentURI is not
401 a valid URI, behavior is undefined.
402 \sa isValid()
403 */
404void QXmlQuery::setQuery(QIODevice *sourceCode, const QUrl &documentURI)
405{
406 if(!sourceCode)
407 {
408 qWarning("A null QIODevice pointer cannot be passed.");
409 return;
410 }
411
412 if(!sourceCode->isReadable())
413 {
414 qWarning("The device must be readable.");
415 return;
416 }
417
418 d->queryURI = QXmlQueryPrivate::normalizeQueryURI(documentURI);
419 d->expression(sourceCode);
420}
421
422/*!
423 \overload
424 The behavior and requirements of this function are the same as for
425 setQuery(QIODevice*, const QUrl&), after the XQuery has been read
426 from the IO device into a string. Because \a sourceCode is already
427 a Unicode string, detection of its encoding is unnecessary.
428*/
429void QXmlQuery::setQuery(const QString &sourceCode, const QUrl &documentURI)
430{
431 Q_ASSERT_X(documentURI.isEmpty() || documentURI.isValid(), Q_FUNC_INFO,
432 "The document URI must be valid.");
433
434 QByteArray query(sourceCode.toUtf8());
435 QBuffer buffer(&query);
436 buffer.open(QIODevice::ReadOnly);
437
438 setQuery(&buffer, documentURI);
439}
440
441/*!
442 Sets this QXmlQuery to the XQuery read from the \a queryURI. Use
443 isValid() after calling this function. If an error occurred reading
444 \a queryURI, e.g., the query does not exist, cannot be read, or is
445 invalid, isValid() will return \e false.
446
447 The supported URI schemes are the same as those in the XQuery
448 function \c{fn:doc}, except that queryURI can be the object of
449 a variable binding.
450
451 \a baseURI is the Base URI of the static context, as defined in the
452 \l {http://www.w3.org/TR/xquery/}{XQuery language}. It is used
453 internally to resolve relative URIs that appear in the query, and
454 for message reporting. If \a baseURI is empty, \a queryURI is used.
455 Otherwise, \a baseURI is used, and it is resolved against the \l
456 {QCoreApplication::applicationFilePath()} {application file path} if
457 it is relative.
458
459 If \a queryURI is empty or invalid, or if \a baseURI is invalid,
460 the behavior of this function is undefined.
461 */
462void QXmlQuery::setQuery(const QUrl &queryURI, const QUrl &baseURI)
463{
464 Q_ASSERT_X(queryURI.isValid(), Q_FUNC_INFO, "The passed URI must be valid.");
465
466 const QUrl canonicalURI(QXmlQueryPrivate::normalizeQueryURI(queryURI));
467 Q_ASSERT(canonicalURI.isValid());
468 Q_ASSERT(!canonicalURI.isRelative());
469 Q_ASSERT(baseURI.isValid() || baseURI.isEmpty());
470
471 d->queryURI = QXmlQueryPrivate::normalizeQueryURI(baseURI.isEmpty() ? queryURI : baseURI);
472
473 QPatternist::AutoPtr<QIODevice> result;
474
475 try
476 {
477 result.reset(QPatternist::AccelTreeResourceLoader::load(canonicalURI, d->m_networkAccessDelegator,
478 d->staticContext()));
479 }
480 catch(const QPatternist::Exception)
481 {
482 /* We do nothing, result will be 0. */
483 }
484
485 if(result)
486 {
487 setQuery(result.data(), d->queryURI);
488 result->close();
489 }
490 else
491 d->recompileRequired();
492}
493
494/*!
495 Binds the variable \a name to the \a value so that $\a name can be
496 used from within the query to refer to the \a value.
497
498 \a name must not be \e null. \a {name}.isNull() must return false.
499 If \a name has already been bound by a previous bindVariable() call,
500 its previous binding will be overridden.
501
502 If \a {value} is null so that \a {value}.isNull() returns true, and
503 \a {name} already has a binding, the effect is to remove the
504 existing binding for \a {name}.
505
506 To bind a value of type QString or QUrl, wrap the value in a
507 QVariant such that QXmlItem's QVariant constructor is called.
508
509 All strings processed by the query must be valid XQuery strings,
510 which means they must contain only XML 1.0 characters. However,
511 this requirement is not checked. If the query processes an invalid
512 string, the behavior is undefined.
513
514 \sa QVariant::isValid(), {QtXDM}{How QVariant maps to XQuery's Data Model},
515 QXmlItem::isNull()
516 */
517void QXmlQuery::bindVariable(const QXmlName &name, const QXmlItem &value)
518{
519 if(name.isNull())
520 {
521 qWarning("The variable name cannot be null.");
522 return;
523 }
524
525 const QPatternist::VariableLoader::Ptr vl(d->variableLoader());
526 const QVariant variant(qVariantFromValue(value));
527
528 /* If the type of the variable changed(as opposed to only the value),
529 * we will have to recompile. */
530 if(vl->invalidationRequired(name, variant) || value.isNull())
531 d->recompileRequired();
532
533 vl->addBinding(name, variant);
534}
535
536/*!
537 \overload
538
539 This function constructs a QXmlName from \a localName using the
540 query's \l {QXmlNamePool} {namespace}. The function then behaves as
541 the overloaded function. It is equivalent to the following snippet.
542
543 \snippet doc/src/snippets/code/src_xmlpatterns_api_qxmlquery.cpp 0
544 */
545void QXmlQuery::bindVariable(const QString &localName, const QXmlItem &value)
546{
547 bindVariable(QXmlName(d->namePool, localName), value);
548}
549
550/*!
551 Binds the variable \a name to the \a device so that $\a name can be
552 used from within the query to refer to the \a device. The QIODevice
553 \a device is exposed to the query as a URI of type \c{xs:anyURI},
554 which can be passed to the \c{fn:doc()} function to be read. E.g.,
555 this function can be used to pass an XML document in memory to
556 \c{fn:doc}.
557
558 \snippet doc/src/snippets/code/src_xmlpatterns_api_qxmlquery.cpp 1
559
560 The caller must ensure that \a device has been opened with at least
561 QIODevice::ReadOnly prior to this binding. Otherwise, behavior is
562 undefined.
563
564 If the query will access an XML document contained in a QString, use
565 a QBuffer as shown in the following snippet. Suppose \e myQString
566 contains \c{<document>content</document>}
567
568 \snippet doc/src/snippets/qxmlquery/bindingExample.cpp 0
569
570 \a name must not be \e null. \a {name}.isNull() must return false.
571 If \a name has already been bound, its previous binding will be
572 overridden. The URI that \a name evaluates to is arbitrary and may
573 change.
574
575 If the type of the variable binding changes (e.g., if a previous
576 binding by the same name was a QVariant, or if there was no previous
577 binding), isValid() will return \c{false}, and recompilation of the
578 query text is required. To recompile the query, call setQuery(). For
579 this reason, bindVariable() should be called before setQuery(), if
580 possible.
581
582 \note \a device must not be deleted while this QXmlQuery exists.
583*/
584void QXmlQuery::bindVariable(const QXmlName &name, QIODevice *device)
585{
586 if(device && !device->isReadable())
587 {
588 qWarning("A null, or readable QIODevice must be passed.");
589 return;
590 }
591
592 if(name.isNull())
593 {
594 qWarning("The variable name cannot be null.");
595 return;
596 }
597
598 const QPatternist::VariableLoader::Ptr vl(d->variableLoader());
599
600 if(device)
601 {
602 const QVariant variant(qVariantFromValue(device));
603
604 if(vl->invalidationRequired(name, variant))
605 d->recompileRequired();
606
607 vl->addBinding(name, variant);
608
609 /* We need to tell the resource loader to discard its document, because
610 * the underlying QIODevice has changed, but the variable name is the
611 * same which means that the URI is the same, and hence the resource
612 * loader will return the document for the old QIODevice.
613 */
614 d->resourceLoader()->clear(QUrl(QLatin1String("tag:trolltech.com,2007:QtXmlPatterns:QIODeviceVariable:") + d->namePool.d->stringForLocalName(name.localName())));
615 }
616 else
617 {
618 vl->removeBinding(name);
619 d->recompileRequired();
620 }
621}
622
623/*!
624 \overload
625
626 If \a localName is a valid \l {QXmlName::isNCName()} {NCName}, this
627 function is equivalent to the following snippet.
628
629 \snippet doc/src/snippets/code/src_xmlpatterns_api_qxmlquery.cpp 2
630
631 A QXmlName is constructed from \a localName, and is passed
632 to the appropriate overload along with \a device.
633
634 \sa QXmlName::isNCName()
635 */
636void QXmlQuery::bindVariable(const QString &localName, QIODevice *device)
637{
638 bindVariable(QXmlName(d->namePool, localName), device);
639}
640
641/*!
642 Evaluates this query and sends the result as a sequence of callbacks
643 to the \l {QAbstractXmlReceiver} {receiver} \a callback. QXmlQuery
644 does not take ownership of \a callback.
645
646 If an error occurs during the evaluation, error messages are sent to
647 messageHandler() and \c false is returned.
648
649 If this query \l {isValid()} {is invalid}, \c{false} is returned
650 and the behavior is undefined. If \a callback is null,
651 behavior is undefined.
652
653 \sa QAbstractXmlReceiver, isValid()
654 */
655bool QXmlQuery::evaluateTo(QAbstractXmlReceiver *callback) const
656{
657 if(!callback)
658 {
659 qWarning("A non-null callback must be passed.");
660 return false;
661 }
662
663 if(isValid())
664 {
665 try
666 {
667 /*
668 * This order is significant. expression() might cause
669 * query recompilation, and as part of that it recreates
670 * the static context. However, if we create the dynamic
671 * context before the query recompilation has been
672 * triggered, it will use the old static context, and
673 * hence old source locations.
674 */
675 const QPatternist::Expression::Ptr expr(d->expression());
676 const QPatternist::DynamicContext::Ptr dynContext(d->dynamicContext(callback));
677 callback->startOfSequence();
678 expr->evaluateToSequenceReceiver(dynContext);
679 callback->endOfSequence();
680 return true;
681 }
682 catch(const QPatternist::Exception)
683 {
684 return false;
685 }
686 }
687 else
688 return false;
689}
690
691/*!
692 Attempts to evaluate the query and returns the results in the
693 \a target \l {QStringList} {string list}.
694
695 If the query \l {isValid()} {is valid} and the evaluation succeeds,
696 true is returned. Otherwise, false is returned and the contents of
697 \a target are undefined.
698
699 The query must evaluate to a sequence of \c{xs:string} values. If
700 the query does not evaluate to a sequence of strings, the values can
701 often be converted by adding a call to \c{string()} at the end of
702 the XQuery.
703
704 If \a target is null, the behavior is undefined.
705 */
706bool QXmlQuery::evaluateTo(QStringList *target) const
707{
708 if(!target)
709 {
710 qWarning("A non-null callback must be passed.");
711 return false;
712 }
713
714 if(isValid())
715 {
716 try
717 {
718 /*
719 * This order is significant. expression() might cause
720 * query recompilation, and as part of that it recreates
721 * the static context. However, if we create the dynamic
722 * context before the query recompilation has been
723 * triggered, it will use the old static context, and
724 * hence old source locations.
725 */
726 const QPatternist::Expression::Ptr expr(d->expression());
727 if(!expr)
728 return false;
729
730 QPatternist::DynamicContext::Ptr dynContext(d->dynamicContext());
731
732 if(!QPatternist::BuiltinTypes::xsString->xdtTypeMatches(expr->staticType()->itemType()))
733 return false;
734
735 const QPatternist::Item::Iterator::Ptr it(expr->evaluateSequence(dynContext));
736 QPatternist::Item next(it->next());
737
738 while(!next.isNull())
739 {
740 target->append(next.stringValue());
741 next = it->next();
742 }
743
744 return true;
745 }
746 catch(const QPatternist::Exception)
747 {
748 return false;
749 }
750 }
751 else
752 return false;
753}
754
755/*!
756 Evaluates the query or stylesheet, and writes the output to \a target.
757
758 QXmlSerializer is used to write the output to \a target. In a future
759 release, it is expected that this function will be changed to
760 respect serialization options set in the stylesheet.
761
762 If an error occurs during the evaluation, error messages are sent to
763 messageHandler() and \c false is returned.
764
765 If \a target is \c null, or is not opened in at least
766 QIODevice::WriteOnly mode, the behavior is undefined. QXmlQuery
767 does not take ownership of \a target.
768
769 \since 4.5
770 \overload
771 */
772bool QXmlQuery::evaluateTo(QIODevice *target) const
773{
774 if(!target)
775 {
776 qWarning("The pointer to the device cannot be null.");
777 return false;
778 }
779
780 if(!target->isWritable())
781 {
782 qWarning("The device must be writable.");
783 return false;
784 }
785
786 QXmlSerializer serializer(*this, target);
787 return evaluateTo(&serializer);
788}
789
790/*!
791 Starts the evaluation and makes it available in \a result. If \a
792 result is null, the behavior is undefined. The evaluation takes
793 place incrementally (lazy evaluation), as the caller uses
794 QXmlResultItems::next() to get the next result.
795
796 \sa QXmlResultItems::next()
797*/
798void QXmlQuery::evaluateTo(QXmlResultItems *result) const
799{
800 if(!result)
801 {
802 qWarning("A null pointer cannot be passed.");
803 return;
804 }
805
806 if(isValid())
807 {
808 try
809 {
810 /*
811 * We don't have the d->expression() calls and
812 * d->dynamicContext() calls in the same order as seen in
813 * QXmlQuery::evaluateTo(), and the reason to why
814 * that isn't a problem, is that we call isValid().
815 */
816 const QPatternist::DynamicContext::Ptr dynContext(d->dynamicContext());
817 result->d_ptr->setDynamicContext(dynContext);
818 result->d_ptr->iterator = d->expression()->evaluateSequence(dynContext);
819 }
820 catch(const QPatternist::Exception)
821 {
822 result->d_ptr->iterator = QPatternist::CommonValues::emptyIterator;
823 result->d_ptr->hasError = true;
824 }
825 }
826 else
827 {
828 result->d_ptr->iterator= QPatternist::CommonValues::emptyIterator;
829 result->d_ptr->hasError = true;
830 }
831}
832
833/*!
834 Evaluates the query, and serializes the output as XML to \a output.
835
836 If an error occurs during the evaluation, error messages are sent to
837 messageHandler(), the content of \a output is undefined and \c false is
838 returned, otherwise \c true is returned.
839
840 If \a output is \c null behavior is undefined. QXmlQuery
841 does not take ownership of \a output.
842
843 Internally, the class QXmlFormatter is used for this.
844 \since 4.5
845 */
846bool QXmlQuery::evaluateTo(QString *output) const
847{
848 Q_ASSERT_X(output, Q_FUNC_INFO,
849 "The input cannot be null");
850
851 QBuffer outputDevice;
852 outputDevice.open(QIODevice::ReadWrite);
853
854 QXmlFormatter formatter(*this, &outputDevice);
855 const bool success = evaluateTo(&formatter);
856
857 outputDevice.close();
858 *output = QString::fromUtf8(outputDevice.data().constData());
859
860 return success;
861}
862
863/*!
864 Returns true if this query is valid. Examples of invalid queries
865 are ones that contain syntax errors or that have not had setQuery()
866 called for them yet.
867 */
868bool QXmlQuery::isValid() const
869{
870 return d->isValid();
871}
872
873/*!
874 Sets the URI resolver to \a resolver. QXmlQuery does not take
875 ownership of \a resolver.
876
877 \sa uriResolver()
878 */
879void QXmlQuery::setUriResolver(const QAbstractUriResolver *resolver)
880{
881 d->uriResolver = resolver;
882}
883
884/*!
885 Returns the query's URI resolver. If no URI resolver has been set,
886 QtXmlPatterns will use the URIs in queries as they are.
887
888 The URI resolver provides a level of abstraction, or \e{polymorphic
889 URIs}. A resolver can rewrite \e{logical} URIs to physical ones, or
890 it can translate obsolete or invalid URIs to valid ones.
891
892 QtXmlPatterns calls the URI resolver for all URIs it encounters,
893 except for namespaces. Specifically, all builtin functions that deal
894 with URIs (\c{fn:doc()}, and \c{fn:doc-available()}).
895
896 In the case of \c{fn:doc()}, the absolute URI is the base URI in the
897 static context (which most likely is the location of the query).
898 Rather than use the URI the user specified, the return value of
899 QAbstractUriResolver::resolve() will be used.
900
901 When QtXmlPatterns calls QAbstractUriResolver::resolve() the
902 absolute URI is the URI mandated by the XQuery language, and the
903 relative URI is the URI specified by the user.
904
905 \sa setUriResolver()
906 */
907const QAbstractUriResolver *QXmlQuery::uriResolver() const
908{
909 return d->uriResolver;
910}
911
912/*!
913 Returns the name pool used by this QXmlQuery for constructing \l
914 {QXmlName} {names}. There is no setter for the name pool, because
915 mixing name pools causes errors due to name confusion.
916 */
917QXmlNamePool QXmlQuery::namePool() const
918{
919 return d->namePool;
920}
921
922/*!
923 Sets the focus to \a item. The focus is the set of items that the
924 context item expression and path expressions navigate from. For
925 example, in the expression \e p/span, the element that \e p
926 evaluates to is the focus for the following expression, \e span.
927
928 The focus can be accessed using the context item expression, i.e.,
929 dot (".").
930
931 By default, the focus is not set and is undefined. It will
932 therefore result in a dynamic error, \c XPDY0002, if the focus
933 is attempted to be accessed. The focus must be set before the
934 query is set with setQuery().
935
936 There is no behavior defined for setting an item which is null.
937
938 */
939void QXmlQuery::setFocus(const QXmlItem &item)
940{
941 d->contextItem = item;
942}
943
944/**
945 * This function should be a private member function of QXmlQuery,
946 * but we don't dare that due to our weird compilers.
947 * @internal
948 * @relates QXmlQuery
949 */
950template<typename TInputType>
951bool setFocusHelper(QXmlQuery *const queryInstance,
952 const TInputType &focusValue)
953{
954 /* We call resourceLoader(), so we have ensured that we have a resourceLoader
955 * that we will share in our copy. */
956 queryInstance->d->resourceLoader();
957
958 QXmlQuery focusQuery(*queryInstance);
959
960 /* Now we use the same, so we own the loaded document. */
961 focusQuery.d->m_resourceLoader = queryInstance->d->m_resourceLoader;
962
963 /* The copy constructor doesn't allow us to copy an existing QXmlQuery and
964 * changing the language at the same time so we need to use private API. */
965 focusQuery.d->queryLanguage = QXmlQuery::XQuery10;
966
967 Q_ASSERT(focusQuery.queryLanguage() == QXmlQuery::XQuery10);
968 focusQuery.bindVariable(QChar::fromLatin1('u'), focusValue);
969 focusQuery.setQuery(QLatin1String("doc($u)"));
970 Q_ASSERT(focusQuery.isValid());
971
972 QXmlResultItems focusResult;
973
974 queryInstance->d->m_resourceLoader = focusQuery.d->m_resourceLoader;
975
976 focusQuery.evaluateTo(&focusResult);
977 const QXmlItem focusItem(focusResult.next());
978
979 if(focusItem.isNull() || focusResult.hasError())
980 return false;
981 else
982 {
983 queryInstance->setFocus(focusItem);
984 return true;
985 }
986}
987
988/*!
989 \since 4.5
990 \overload
991
992 Sets the focus to be the document located at \a documentURI and
993 returns true. If \a documentURI cannot be loaded, false is returned.
994 It is undefined at what time the document may be loaded. When
995 loading the document, the message handler and URI resolver set on
996 this QXmlQuery are used.
997
998 If \a documentURI is empty or is not a valid URI, the behavior of
999 this function is undefined.
1000 */
1001bool QXmlQuery::setFocus(const QUrl &documentURI)
1002{
1003 Q_ASSERT_X(documentURI.isValid() && !documentURI.isEmpty(),
1004 Q_FUNC_INFO,
1005 "The URI passed must be valid.");
1006
1007 return setFocusHelper(this, QVariant(documentURI));
1008}
1009
1010/*!
1011
1012 Sets the focus to be the \a document read from the QIODevice and
1013 returns true. If \a document cannot be loaded, false is returned.
1014
1015 QXmlQuery does not take ownership of \a document. The user
1016 guarantees that a document is available from the \a document device
1017 and that the document is not empty. The device must be opened in at
1018 least read-only mode. \a document must stay in scope as long as the
1019 current query is active.
1020
1021 \since 4.5
1022 \overload
1023 */
1024bool QXmlQuery::setFocus(QIODevice *document)
1025{
1026 if(!document)
1027 {
1028 qWarning("A null QIODevice pointer cannot be passed.");
1029 return false;
1030 }
1031
1032 if(!document->isReadable())
1033 {
1034 qWarning("The device must be readable.");
1035 return false;
1036 }
1037
1038 return setFocusHelper(this, document);
1039}
1040
1041/*!
1042 Returns a value indicating what this QXmlQuery is being used for.
1043 The default is QXmlQuery::XQuery10, which means the QXmlQuery is
1044 being used for running XQuery and XPath queries. QXmlQuery::XSLT20
1045 can also be returned, which indicates the QXmlQuery is for running
1046 XSL-T spreadsheets.
1047
1048 \since 4.5
1049 */
1050QXmlQuery::QueryLanguage QXmlQuery::queryLanguage() const
1051{
1052 return d->queryLanguage;
1053}
1054
1055/*!
1056 Sets the \a name of the initial template. The initial template is
1057 the one the processor calls first, instead of attempting to match a
1058 template to the context node (if any). If an initial template is not
1059 set, the standard order of template invocation will be used.
1060
1061 This function only applies when using QXmlQuery to process XSL-T
1062 stylesheets. The name becomes part of the compiled stylesheet.
1063 Therefore, this function must be called before calling setQuery().
1064
1065 If the stylesheet has no template named \a name, the processor will
1066 use the standard order of template invocation.
1067
1068 \since 4.5
1069 \sa initialTemplateName()
1070 */
1071void QXmlQuery::setInitialTemplateName(const QXmlName &name)
1072{
1073 d->initialTemplateName = name;
1074}
1075
1076/*!
1077 \overload
1078
1079 Sets the name of the initial template to \a localName, which must be
1080 a valid \l{QXmlName::localName()} {local name}. The initial template
1081 is the one the processor calls first, instead of attempting to match
1082 a template to the context node (if any). If an initial template is
1083 not set, the standard order of template invocation will be used.
1084
1085 This function only applies when using QXmlQuery to process XSL-T
1086 stylesheets. The name becomes part of the compiled stylesheet.
1087 Therefore, this function must be called before calling setQuery().
1088
1089 If \a localName is not a valid \l{QXmlName::localName()} {local
1090 name}, the effect is undefined. If the stylesheet has no template
1091 named \a localName, the processor will use the standard order of
1092 template invocation.
1093
1094 \since 4.5
1095 \sa initialTemplateName()
1096 */
1097void QXmlQuery::setInitialTemplateName(const QString &localName)
1098{
1099 Q_ASSERT_X(QXmlName::isNCName(localName),
1100 Q_FUNC_INFO,
1101 "The name passed must be a valid NCName.");
1102 setInitialTemplateName(QXmlName(d->namePool, localName));
1103}
1104
1105/*!
1106 Returns the name of the XSL-T stylesheet template that the processor
1107 will call first when running an XSL-T stylesheet. This function only
1108 applies when using QXmlQuery to process XSL-T stylesheets. By
1109 default, no initial template is set. In that case, a default
1110 constructed QXmlName is returned.
1111
1112 \since 4.5
1113 */
1114QXmlName QXmlQuery::initialTemplateName() const
1115{
1116 return d->initialTemplateName;
1117}
1118
1119/*!
1120 Sets the network manager to \a newManager.
1121 QXmlQuery does not take ownership of \a newManager.
1122
1123 \sa networkAccessManager()
1124 \since 4.5
1125 */
1126void QXmlQuery::setNetworkAccessManager(QNetworkAccessManager *newManager)
1127{
1128 d->m_networkAccessDelegator->m_genericManager = newManager;
1129}
1130
1131/*!
1132 Returns the network manager, or 0 if it has not been set.
1133
1134 \sa setNetworkAccessManager()
1135 \since 4.5
1136 */
1137QNetworkAccessManager *QXmlQuery::networkAccessManager() const
1138{
1139 return d->m_networkAccessDelegator->m_genericManager;
1140}
1141
1142/*!
1143 Binds the result of the query \a query, to a variable by name \a name.
1144
1145 Evaluation of \a query will be commenced when this function is called.
1146
1147 If \a query is invalid, behavior is undefined. \a query will be copied.
1148
1149 \since 4.5
1150 \sa isValid()
1151 */
1152void QXmlQuery::bindVariable(const QXmlName &name, const QXmlQuery &query)
1153{
1154 Q_ASSERT_X(query.isValid(), Q_FUNC_INFO, "The query being bound must be valid.");
1155
1156 const QPatternist::VariableLoader::Ptr vl(d->variableLoader());
1157 const QVariant variant(qVariantFromValue(query));
1158
1159 if(vl->invalidationRequired(name, variant))
1160 d->recompileRequired();
1161
1162 vl->addBinding(name, variant);
1163}
1164
1165/*!
1166 \overload
1167
1168 Has the same behavior and effects as the function being overloaded, but takes
1169 the variable name \a localName as a QString. \a query is used as in the
1170 overloaded function.
1171
1172 \since 4.5
1173 */
1174void QXmlQuery::bindVariable(const QString &localName, const QXmlQuery &query)
1175{
1176 return bindVariable(QXmlName(d->namePool, localName), query);
1177}
1178
1179QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.