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

source code of qtxmlpatterns/src/xmlpatterns/api/qxmlquery.cpp