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