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

Last change on this file since 846 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

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