src/xmlpatterns/api/qabstractxmlnodemodel.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 <QVector>
       
    43 
       
    44 #include "qabstractxmlnodemodel_p.h"
       
    45 #include "qabstractxmlreceiver.h"
       
    46 #include "qcommonvalues_p.h"
       
    47 #include "qemptyiterator_p.h"
       
    48 #include "qitemmappingiterator_p.h"
       
    49 #include "qitem_p.h"
       
    50 #include "qnamespaceresolver_p.h"
       
    51 #include "qsequencemappingiterator_p.h"
       
    52 #include "qsingletoniterator_p.h"
       
    53 
       
    54 #include "qabstractxmlnodemodel.h"
       
    55 
       
    56 QT_BEGIN_NAMESPACE
       
    57 
       
    58 using namespace QPatternist;
       
    59 
       
    60 typedef QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QXmlNodeModelIndex> > QXmlNodeModelIndexIteratorPointer;
       
    61 
       
    62 /**
       
    63  * @file
       
    64  * @short Contains the implementation of QAbstractXmlNodeModel.
       
    65  */
       
    66 
       
    67 bool QAbstractXmlNodeModel::isIgnorableInDeepEqual(const QXmlNodeModelIndex &n)
       
    68 {
       
    69     Q_ASSERT(!n.isNull());
       
    70     const QXmlNodeModelIndex::NodeKind nk = n.kind();
       
    71     return nk == QXmlNodeModelIndex::ProcessingInstruction ||
       
    72            nk == QXmlNodeModelIndex::Comment;
       
    73 }
       
    74 
       
    75 
       
    76 /*!
       
    77   \class QAbstractXmlNodeModel
       
    78   \brief The QAbstractXmlNodeModel class is an abstract base class for modeling non-XML data to look like XML for QXmlQuery.
       
    79   \threadsafe
       
    80   \since 4.4
       
    81   \ingroup xml-tools
       
    82 
       
    83   The QAbstractXmlNodeModel specifies the interface that a node model
       
    84   must implement for that node model be accessible to the query engine
       
    85   for processing XQuery queries.  A node model represents data as a
       
    86   structure that can be queried as if the data were XML.
       
    87 
       
    88   The node model represented by a subclass of QAbstractXmlNodeModel is
       
    89   meant to be accessed by the QtXmlPatterns query engine. If the API
       
    90   seems a little strange in a few places, it is because the member
       
    91   functions are called by the query engine as it evaluates an
       
    92   XQuery. They aren't meant to be used programatically.
       
    93 
       
    94   \section1 Usage
       
    95 
       
    96   QAbstractXmlNodeModel bridges the gap between the arbitrary structure
       
    97   of the non-XML data to be queried and the well-defined structure of
       
    98   XML data understood by QXmlQuery.
       
    99 
       
   100   Consider a chemistry application that reads the file \c
       
   101   chemistryData, which contains non-XML data that represents a
       
   102   chemical structure composed of molecules and atoms. The application
       
   103   will query this chemistry data with an XQuery it reads from file \c
       
   104   queryFile. We write a custom subclass of QAbstractXmlNodeModel (\c
       
   105   ChemistryNodeModel) that reads \c chemistryData and builds a data
       
   106   structure, perhaps composed of objects of our own classes \c
       
   107   molecule and \c atom.  Clearly, this data structure is not XML. Our
       
   108   custom subclass will know how to traverse this non-XML structure and
       
   109   present it through the \l
       
   110   {http://www.w3.org/TR/xpath-datamodel/}{XPath Data Model interface}.
       
   111 
       
   112   \snippet doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlnodemodel.cpp 1
       
   113 
       
   114   The application first creates an instance of QXmlQuery and calls \l
       
   115   {QXmlQuery::setQuery()}{setQuery()} to read \c queryFile containing
       
   116   the XQuery we want to run. Then it creates an instance of our custom
       
   117   node model class, \c ChemistryNodeModel, which is a subclass of
       
   118   QAbstractXmlNodeModel. Its constructor is called with the \l
       
   119   {QXmlNamePool} {name pool} obtained from our QXmlQuery, and with the
       
   120   \c chemistryFile containing the structure of molecules and atoms to
       
   121   be queried. The \l {QXmlNamePool} {name pool} is required because
       
   122   our custom node model has the member function \l
       
   123   {QAbstractXmlNodeModel::name()} {name()}, which returns the \l
       
   124   {QXmlName} {name} of any node in the model. The \l {QXmlQuery}
       
   125   {query} and the custom node model must use the same name pool for
       
   126   constructing these \l {QXmlName} {names}. The constructor would then
       
   127   read \c chemistryFile and build the custom node model structure.
       
   128 
       
   129   To connect the \c query to the custom node model, we must bind a
       
   130   variable name used in the query to a node in the model. The variable
       
   131   can then be used in the query as a starting node. First, an \l
       
   132   {QXmlNodeModelIndex} {index} for the desired starting node is
       
   133   retrieved by calling QAbstractXmlNodeModel::createIndex(). Then the
       
   134   index is bound to a variable name, in this case \c queryRoot, by
       
   135   passing the name and the index to QXmlQuery::bindVariable(). The
       
   136   query can then use a variable reference \c $queryRoot to refer to
       
   137   the starting node. Note that if the \l {QXmlQuery} {query} uses
       
   138   multiple variable references, a call to QXmlQuery::bindVariable()
       
   139   is required to bind each different variable name to a node in the
       
   140   model.
       
   141 
       
   142   The query is executed when the application calls one of the
       
   143   QXmlQuery evaluation functions. The application uses
       
   144   QXmlQuery::evaluateTo(QAbstractXmlReceiver *), because it then uses
       
   145   a \l {QXmlSerializer} {serializer} to out the query result as XML to
       
   146   \c stdout. We could have used QXmlQuery::evaluateTo(QXmlResultItems
       
   147   *) to get a list of result items, or
       
   148   QXmlQuery::evaluateTo(QStringList *) if the query evaluated to a
       
   149   sequence of \c {xs:string} values.
       
   150 
       
   151   During query execution, the engine iterates over the node model
       
   152   using nextFromSimpleAxis() to get the \l {QXmlNodeModelIndex}
       
   153   {index} of the next node to be visited. The engine can get the name
       
   154   of a node by calling name() with the node's \l {QXmlNodeModelIndex}
       
   155   {index}. stringValue(), baseUri(), documentUri() and kind() are also
       
   156   called as needed with a node \l {QXmlNodeModelIndex} {index}.
       
   157 
       
   158   The example demonstrates the standard pattern for using a subclass
       
   159   of QAbstractXmlNodeModel in combination with QXmlQuery to perform
       
   160   an XQuery.
       
   161 
       
   162   \list 1
       
   163 
       
   164     \o Instantiate QXmlQuery and give it the XQuery to be run;
       
   165 
       
   166     \o Instantiate a subclass of QAbstractXmlNodeModel or
       
   167     QSimpleXmlNodeModel;
       
   168 
       
   169     \o Retrieve a QXmlNodeModelIndex for the node in the model where
       
   170     the QXmlQuery should start the query;
       
   171 
       
   172     \o Use QXmlQuery::bindVariable() to bind the QXmlNodeModelIndex
       
   173     to \c {$variable name};
       
   174 
       
   175     \o Call one of the QXmlQuery evaluation functions to run the
       
   176     query.
       
   177 
       
   178   \endlist
       
   179 
       
   180   \section1 Subclassing
       
   181 
       
   182   Because the \l {http://www.w3.org/TR/xpath-datamodel/}{XPath Data Model
       
   183   interface} presented by QAbstractXmlNodeModel allows QXmlQuery to
       
   184   operate on non-XML data as if it were XML, implementing subclasses
       
   185   of QAbstractXmlNodeModel can involve a significant amount of
       
   186   work. The QSimpleXmlNodeModel class is provided to simplify the
       
   187   implementation for many common use cases.
       
   188 
       
   189   \section1 Thread Safety
       
   190 
       
   191   Because the node model can be accessed concurrently by threads in
       
   192   the QtXmlPatterns module, subclasses of QAbstractXmlNodeModel must
       
   193   be written to be \l{Reentrancy and Thread-Safety}{thread-safe}.
       
   194   Classes that simplify implementing thread-safety include QReadLocker
       
   195   and QWriteLocker.
       
   196 
       
   197   See the example \l{File System Example} for a demonstration.
       
   198  */
       
   199 
       
   200 /*!
       
   201   \enum QXmlNodeModelIndex::Constants
       
   202 
       
   203   \value ForwardAxis All forward axes include this flag.
       
   204   \value ReverseAxis All reverse axes include this flag.
       
   205  */
       
   206 
       
   207 /*!
       
   208   \enum QXmlNodeModelIndex::DocumentOrder
       
   209 
       
   210   Identifies the specific node comparison operator that should be
       
   211   used.
       
   212 
       
   213   \value Precedes Signifies the \c \<\< operator. Test whether the
       
   214          first operand precedes the second in the document.
       
   215 
       
   216   \value Follows Signifies the \c \>\> operator. Test whether the
       
   217                  first operand follows the second in the document.
       
   218 
       
   219   \value Is Signifies the \c is operator. Test whether two nodes have
       
   220   the same node identity.
       
   221  */
       
   222 
       
   223 /*!
       
   224   \enum QAbstractXmlNodeModel::SimpleAxis
       
   225 
       
   226   Four axes that each contain one node only.
       
   227 
       
   228   \value Parent The parent of the context node
       
   229   \value FirstChild The first child of the context node
       
   230   \value PreviousSibling The previous child of the context node
       
   231   \value NextSibling The next child of the context node
       
   232 */
       
   233 
       
   234 /*!
       
   235  \enum QXmlNodeModelIndex::Axis
       
   236  \internal
       
   237 
       
   238    Identify the axes emanating from a node.
       
   239 
       
   240    The axes AxisChild, AxisDescendant, AxisAttribute, AxisSelf,
       
   241    AxisDescendantOrSelf, AxisFollowingSibling, and AxisFollowing are
       
   242    forward axes.
       
   243 
       
   244    The axes AxisParent, AxisAncestor, AxisPrecedingSibling,
       
   245    AxisPreceding and AxisAncestorOrSelf are reverse axes.
       
   246 
       
   247    \sa {http://www.w3.org/TR/xquery/#axes}{XQuery 1.0: An XML Query Language, 3.2.1.1 Axes}
       
   248 
       
   249    \value AxisChild                The \c child axis.
       
   250 
       
   251    \value AxisDescendant           The \c descendant axis.
       
   252 
       
   253    \value AxisAttribute            The \c attribute axis. Note: There
       
   254                                    is a node kind named \c{Attribute}.
       
   255 
       
   256    \value AxisSelf                 The \c self axis.
       
   257 
       
   258    \value AxisDescendantOrSelf     The \c descendant-or-self axis.
       
   259 
       
   260    \value AxisFollowingSibling     The \c following-sibling axis.
       
   261 
       
   262    \value AxisNamespace            The \c namespace axis. Note: Does
       
   263                                    not exist in XQuery; deprecated in
       
   264                                    XPath 2.0 (optionally supported);
       
   265                                    mandatory in XPath 1.0.
       
   266 
       
   267    \value AxisFollowing            The \c following axis.
       
   268 
       
   269    \value AxisParent               The \c parent axis.
       
   270 
       
   271    \value AxisAncestor             The \c ancestor axis.
       
   272 
       
   273    \value AxisPrecedingSibling     The \c preceding-sibling axis.
       
   274 
       
   275    \value AxisPreceding            The \c preceding axis.
       
   276 
       
   277    \value AxisAncestorOrSelf       The \c ancestor-or-self axis.
       
   278 */
       
   279 
       
   280 using namespace QPatternist;
       
   281 
       
   282 /*!
       
   283   Default constructor.
       
   284  */
       
   285 QAbstractXmlNodeModel::QAbstractXmlNodeModel() : d_ptr(0)
       
   286 {
       
   287 }
       
   288 
       
   289 /*!
       
   290  \internal
       
   291 
       
   292  Takes the d-pointer.
       
   293 
       
   294  */
       
   295 QAbstractXmlNodeModel::QAbstractXmlNodeModel(QAbstractXmlNodeModelPrivate *d) : d_ptr(d)
       
   296 {
       
   297 }
       
   298 
       
   299 /*!
       
   300   Destructor.
       
   301  */
       
   302 QAbstractXmlNodeModel::~QAbstractXmlNodeModel()
       
   303 {
       
   304 }
       
   305 
       
   306 /*!
       
   307   \typedef QAbstractXmlNodeModel::List
       
   308 
       
   309   A \l{QList}{list} of \l{QExplicitlySharedDataPointer} {smart
       
   310   pointers} to instances of QAbstractXmlNodeModel.
       
   311 
       
   312   \sa QExplicitlySharedDataPointer
       
   313  */
       
   314 
       
   315 /*!
       
   316   \typedef QAbstractXmlNodeModel::Ptr
       
   317 
       
   318   A \l {QExplicitlySharedDataPointer} {smart pointer} to an
       
   319   instance of QAbstractXmlNodeModel.
       
   320 
       
   321   \sa QExplicitlySharedDataPointer
       
   322  */
       
   323 
       
   324 /*!
       
   325   \fn QUrl QAbstractXmlNodeModel::baseUri(const QXmlNodeModelIndex &n) const
       
   326 
       
   327   Returns the base URI for the node whose index is \a n. The caller
       
   328   guarantees that \a n is not \c null and that it belongs to a node
       
   329   in this node model.
       
   330 
       
   331   The base URI of a node can be extracted using the \c fn:base-uri()
       
   332   function. The base URI is typically used for resolving relative URIs
       
   333   that appear in the node or its children. It is conformant to just
       
   334   return the document URI, although that might not properly reflect
       
   335   the underlying data.
       
   336 
       
   337   This function maps to the \c dm:base-uri accessor, which returns
       
   338   a base URI according to the following:
       
   339 
       
   340   \list
       
   341 
       
   342   \o For document nodes, the base URI and the document URI are the same.
       
   343 
       
   344   \o For elements, the base URI is the URI appearing in the element's
       
   345      \c xml:base attribute, if present, or it is resolved to the
       
   346      parent element's base URI.
       
   347 
       
   348   \o Namespace nodes have no base URI.
       
   349 
       
   350   \o The base URI for a processing instruction, comment, attribute,
       
   351   or text node is the base URI of the node's parent element.
       
   352 
       
   353   \endlist
       
   354 
       
   355   The implementation guarantees to return a valid QUrl, or a default
       
   356   constructed QUrl. If a node has no base URI, as in the case where a
       
   357   comment has no parent, a default constructed QUrl is returned.
       
   358 
       
   359    \sa {http://www.w3.org/TR/xpath-datamodel/#dm-base-uri}{XQuery 1.0 and XPath 2.0 Data Model (XDM), 5.2 base-uri Accessor}
       
   360  */
       
   361 
       
   362 /*!
       
   363   \fn QUrl QAbstractXmlNodeModel::documentUri(const QXmlNodeModelIndex &n) const
       
   364 
       
   365   Returns the document URI of \a n. The document URI identifies the
       
   366   resource which is the document. For example, the document could be a
       
   367   regular file, e.g., \c{file:/}, or it could be the \c{http://} URL of
       
   368   the location of a file. The document URI is used for resolving URIs
       
   369   and to simply know where the document is.
       
   370 
       
   371   If the node model maps to a URI in a natural way, return that URI.
       
   372   Otherwise, return the company or product URI. The document URI can
       
   373   be any URI as long as its valid and absolute.
       
   374 
       
   375   The caller guarantees that \a n is not \c null and that it belongs
       
   376   to this QAbstractXmlNodeModel.
       
   377 
       
   378   This function maps to the \c dm:document-uri accessor, which
       
   379   returns a document URI according to the following:
       
   380 
       
   381   \list
       
   382 
       
   383   \o If \a n is a document node, return an absolute QUrl containing
       
   384      the document URI, or a default constructed QUrl. The latter
       
   385      signals that no document URI is available for the document node.
       
   386 
       
   387   \o For all other nodes, return a default constructed QUrl.
       
   388 
       
   389   \endlist
       
   390 
       
   391   \sa {http://www.w3.org/TR/xpath-datamodel/#dm-document-uri}{XQuery 1.0 and XPath 2.0 Data Model (XDM), 5.4 document-uri Accessor}
       
   392   \sa QUrl::isValid(), QUrl::isRelative()
       
   393  */
       
   394 
       
   395 /*
       
   396 ### Qt 5:
       
   397 
       
   398 Add the function:
       
   399 
       
   400     virtual QSourceLocation sourceLocation(const QXmlNodeModelIndex &nodeIndex) const = 0;
       
   401 
       
   402 Such that the data model can communicate back source locations.
       
   403  */
       
   404 
       
   405 /*!
       
   406   \fn QXmlNodeModelIndex::NodeKind QAbstractXmlNodeModel::kind(const QXmlNodeModelIndex &ni) const
       
   407 
       
   408   Returns a value indicating the kind of node identified by \a ni.
       
   409   The caller guarantees that \a ni is not null and that it identifies
       
   410   a node in this node model. This function maps to the \c
       
   411   dm:node-kind() accessor.
       
   412 
       
   413   \sa {http://www.w3.org/TR/xpath-datamodel/#dm-node-kind}{XQuery 1.0 and XPath 2.0 Data Model (XDM), 5.10 node-kind Accessor}
       
   414  */
       
   415 
       
   416 /*!
       
   417   \fn QXmlNodeModelIndex::DocumentOrder QAbstractXmlNodeModel::compareOrder(const QXmlNodeModelIndex &ni1, const QXmlNodeModelIndex &ni2) const
       
   418 
       
   419   This function returns the relative document order for the
       
   420   nodes indexed by \a ni1 and \a ni2. It is used for the \c Is
       
   421   operator and for sorting nodes in document order.
       
   422 
       
   423   The caller guarantees that \a ni1 and \a ni2 are not \c null and
       
   424   that both identify nodes in this node model.
       
   425 
       
   426   If \a ni1 is identical to \a ni2, QXmlNodeModelIndex::Is is returned.
       
   427   If \a ni1 precedes \a ni2 in document order, QXmlNodeModelIndex::Precedes
       
   428   is returned. If \a ni1 follows \a ni2 in document order,
       
   429   QXmlNodeModelIndex::Follows is returned.
       
   430 
       
   431   \sa {http://www.w3.org/TR/xpath-datamodel/#document-order}{XQuery 1.0 and XPath 2.0 Data Model (XDM), 2.4 Document Order}
       
   432  */
       
   433 
       
   434 /*!
       
   435   \fn QXmlNodeModelIndex QAbstractXmlNodeModel::root(const QXmlNodeModelIndex &n) const
       
   436 
       
   437   Returns the root node of the tree that contains the node whose index
       
   438   is \a n. The caller guarantees that \a n is not \c null and that it
       
   439   identifies a node in this node model.
       
   440 
       
   441   If \a n identifies a node that is a direct child of the root,
       
   442   parent() would return the same QXmlNodeModelIndex returned by
       
   443   this function.
       
   444  */
       
   445 
       
   446 namespace QPatternist
       
   447 {
       
   448     class MergeIterator
       
   449     {
       
   450     public:
       
   451         inline MergeIterator()
       
   452         {
       
   453         }
       
   454 
       
   455         inline
       
   456         QXmlNodeModelIndexIteratorPointer
       
   457         mapToSequence(const QXmlNodeModelIndexIteratorPointer &it,
       
   458                       const DynamicContext::Ptr &) const
       
   459         {
       
   460             return it;
       
   461         }
       
   462 
       
   463     private:
       
   464         Q_DISABLE_COPY(MergeIterator)
       
   465     };
       
   466 
       
   467     static const MergeIterator mergeIterator;
       
   468 
       
   469     /**
       
   470      * One might wonder, why not use makeVectorIterator() directly on a QVector
       
   471      * with iterators?
       
   472      *
       
   473      * A problem emerges QAbstractXmlForwardIterator::copy(). All "meta
       
   474      * iterators" that contain other iterators and so forth, propagate the
       
   475      * copy() call such that all involved iterators are copied. However, if we
       
   476      * have a ListIterator of iterators it isn't aware of that it contains
       
   477      * iterators. Hence, we have this class which is specialized(not in the
       
   478      * template sense) on iterators, and hence copies them appropriately.
       
   479      */
       
   480     class IteratorVector : public ListIterator<QXmlNodeModelIndexIteratorPointer, QVector<QXmlNodeModelIndexIteratorPointer> >
       
   481     {
       
   482         typedef QVector<QXmlNodeModelIndexIteratorPointer> ItVector;
       
   483     public:
       
   484         typedef QAbstractXmlForwardIterator<QXmlNodeModelIndexIteratorPointer>::Ptr Ptr;
       
   485 
       
   486         IteratorVector(const ItVector &in) : ListIterator<QXmlNodeModelIndexIteratorPointer, QVector<QXmlNodeModelIndexIteratorPointer> >(in)
       
   487         {
       
   488         }
       
   489 
       
   490         virtual QAbstractXmlForwardIterator<QXmlNodeModelIndexIteratorPointer>::Ptr copy() const
       
   491         {
       
   492             ItVector result;
       
   493 
       
   494             for(int i = 0; i < m_list.count(); ++i)
       
   495                 result.append(m_list.at(i)->copy());
       
   496 
       
   497             return Ptr(new IteratorVector(result));
       
   498         }
       
   499     };
       
   500 }
       
   501 
       
   502 /*!
       
   503  \internal
       
   504  This function is not a private member of QAbstractXmlNodeModel
       
   505  because it would be messy to forward declare the required types.
       
   506 */
       
   507 static inline QXmlNodeModelIndexIteratorPointer mergeIterators(const QXmlNodeModelIndex &node,
       
   508                                                                const QXmlNodeModelIndexIteratorPointer &it2)
       
   509 {
       
   510     QVector<QXmlNodeModelIndexIteratorPointer> iterators;
       
   511     iterators.append(makeSingletonIterator(node));
       
   512     iterators.append(it2);
       
   513 
       
   514     return makeSequenceMappingIterator<QXmlNodeModelIndex>(&mergeIterator,
       
   515                                                            IteratorVector::Ptr(new IteratorVector(iterators)),
       
   516                                                            DynamicContext::Ptr());
       
   517 }
       
   518 
       
   519 inline QAbstractXmlForwardIterator<QXmlNodeModelIndex>::Ptr
       
   520 QAbstractXmlNodeModel::mapToSequence(const QXmlNodeModelIndex &ni,
       
   521                                      const DynamicContext::Ptr &) const
       
   522 {
       
   523     Q_ASSERT(!ni.isNull());
       
   524     /* Since we pass in this here, mapToSequence is used recursively. */
       
   525     return mergeIterators(ni, makeSequenceMappingIterator<QXmlNodeModelIndex>(this,
       
   526                                                                               ni.iterate(QXmlNodeModelIndex::AxisChild),
       
   527                                                                               DynamicContext::Ptr()));
       
   528 }
       
   529 
       
   530 /*!
       
   531   \fn QVector<QXmlNodeModelIndex> QAbstractXmlNodeModel::attributes(const QXmlNodeModelIndex &element) const
       
   532 
       
   533   Returns the attributes of \a element. The caller guarantees
       
   534   that \a element is an element in this node model.
       
   535  */
       
   536 
       
   537 /*!
       
   538   \internal
       
   539 
       
   540   Performs navigation, starting from \a ni, by returning an
       
   541   QAbstractXmlForwardIterator that returns nodes the \a axis emanating
       
   542   from \a ni.
       
   543 
       
   544   The implementation returns the nodes on the \a axis, without
       
   545   duplicates and in \a axis order. This means that if \a axis is a
       
   546   reverse axis, which is the case for the \c parent, \c ancestor, \c
       
   547   ancestor-or-self, \c preceding, and \c preceding-sibling, the nodes
       
   548   are delivered in reverse document order. Otherwise the nodes are
       
   549   delivered in document order.
       
   550 
       
   551   The implementor guarantees that the nodes delivered for the axes are
       
   552   consistent with the XPath Data Model. This just implies common
       
   553   sense, e.g., The child axis for a comment node can't contain any
       
   554   children; a document node can't be a child of an element, etc.
       
   555   Attributes aren't considered children of an element, but are only
       
   556   available on AxisAttribute.
       
   557 
       
   558   The value past in \a axis is not guaranteed based on what is used in
       
   559   a query. QtXmlPatterns may call this function arbitrarily with any
       
   560   value for \a axis. This is because QtXmlPatterns may rewrite queries
       
   561   to be more efficient, using axes in different ways from the original
       
   562   query.
       
   563 
       
   564   QAbstractXmlNodeModel::Axis has a good overview of the axes and what
       
   565   they select.
       
   566 
       
   567   The caller guarantees that \a ni is not \c null and that it belongs
       
   568   to this QAbstractXmlNodeModel instance.
       
   569 
       
   570   Implementing iterate() can involve significant work, since it
       
   571   requires different iterators for all the axes used. In the worst
       
   572   case, it could require writing as many QAbstractXmlForwardIterator
       
   573   subclasses as there are axes, but the number can often be reduced
       
   574   with clever use of lists and template classes. It is better to use
       
   575   or subclass QSimpleXmlNodeModel, which makes it easier to write the
       
   576   node navigation code without loss of efficiency or flexibility.
       
   577 
       
   578   \sa QSimpleXmlNodeModel
       
   579   \sa QXmlNodeModelIndex::Axis
       
   580   \sa {http://www.w3.org/TR/xquery/#axes}{XQuery 1.0: An XML Query Language, 3.2.1.1 Axes}
       
   581   \sa {http://www.w3.org/TR/xpath-datamodel/}{W3CXQuery 1.0 and XPath 2.0 Data Model (XDM)}
       
   582  */
       
   583 QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QXmlNodeModelIndex> >
       
   584 QAbstractXmlNodeModel::iterate(const QXmlNodeModelIndex &ni,
       
   585                                QXmlNodeModelIndex::Axis axis) const
       
   586 {
       
   587     /* Returns iterators that track state and calls nextFromSimpleAxis()
       
   588      * iteratively. Typically, when sub-classing QSimpleXmlNodeModel,
       
   589      * you don't reimplement this function, but instead implement
       
   590      * nextFromSimpleAxis(). */
       
   591 
       
   592     switch(axis)
       
   593     {
       
   594         case QXmlNodeModelIndex::AxisSelf:
       
   595             return makeSingletonIterator(ni);
       
   596         case QXmlNodeModelIndex::AxisParent:
       
   597         {
       
   598             if(kind(ni) == QXmlNodeModelIndex::Document)
       
   599                 return makeEmptyIterator<QXmlNodeModelIndex>();
       
   600             else
       
   601                 return makeSingletonIterator(nextFromSimpleAxis(Parent, ni));
       
   602         }
       
   603         case QXmlNodeModelIndex::AxisNamespace:
       
   604             return makeEmptyIterator<QXmlNodeModelIndex>();
       
   605         case QXmlNodeModelIndex::AxisAncestor:
       
   606         {
       
   607             QList<QXmlNodeModelIndex> ancestors;
       
   608             QXmlNodeModelIndex ancestor = nextFromSimpleAxis(Parent, ni);
       
   609 
       
   610             while(!ancestor.isNull())
       
   611             {
       
   612                 ancestors.append(ancestor);
       
   613                 ancestor = nextFromSimpleAxis(Parent, ancestor);
       
   614             }
       
   615 
       
   616             return makeListIterator(ancestors);
       
   617         }
       
   618         case QXmlNodeModelIndex::AxisAncestorOrSelf:
       
   619         {
       
   620             QList<QXmlNodeModelIndex> ancestors;
       
   621             ancestors.append(ni);
       
   622             QXmlNodeModelIndex ancestor = nextFromSimpleAxis(Parent, ni);
       
   623 
       
   624             while(!ancestor.isNull())
       
   625             {
       
   626                 ancestors.append(ancestor);
       
   627                 ancestor = nextFromSimpleAxis(Parent, ancestor);
       
   628             }
       
   629 
       
   630             return makeListIterator(ancestors);
       
   631         }
       
   632         case QXmlNodeModelIndex::AxisPrecedingSibling:
       
   633         {
       
   634             QList<QXmlNodeModelIndex> preceding;
       
   635             QXmlNodeModelIndex sibling = nextFromSimpleAxis(PreviousSibling, ni);
       
   636 
       
   637             while(!sibling.isNull())
       
   638             {
       
   639                 preceding.append(sibling);
       
   640                 sibling = nextFromSimpleAxis(PreviousSibling, sibling);
       
   641             }
       
   642 
       
   643             return makeListIterator(preceding);
       
   644         }
       
   645         case QXmlNodeModelIndex::AxisFollowingSibling:
       
   646         {
       
   647             QList<QXmlNodeModelIndex> preceding;
       
   648             QXmlNodeModelIndex sibling = nextFromSimpleAxis(NextSibling, ni);
       
   649 
       
   650             while(!sibling.isNull())
       
   651             {
       
   652                 preceding.append(sibling);
       
   653                 sibling = nextFromSimpleAxis(NextSibling, sibling);
       
   654             }
       
   655 
       
   656             return makeListIterator(preceding);
       
   657         }
       
   658         case QXmlNodeModelIndex::AxisChildOrTop:
       
   659         {
       
   660             if(nextFromSimpleAxis(Parent, ni).isNull())
       
   661             {
       
   662                 switch(kind(ni))
       
   663                 {
       
   664                     case QXmlNodeModelIndex::Comment:
       
   665                     /* Fallthrough. */
       
   666                     case QXmlNodeModelIndex::ProcessingInstruction:
       
   667                     /* Fallthrough. */
       
   668                     case QXmlNodeModelIndex::Element:
       
   669                     /* Fallthrough. */
       
   670                     case QXmlNodeModelIndex::Text:
       
   671                         return makeSingletonIterator(ni);
       
   672                     case QXmlNodeModelIndex::Attribute:
       
   673                     /* Fallthrough. */
       
   674                     case QXmlNodeModelIndex::Document:
       
   675                     /* Fallthrough. */
       
   676                     case QXmlNodeModelIndex::Namespace:
       
   677                         /* Do nothing. */;
       
   678                 }
       
   679             }
       
   680 
       
   681             /* Else, fallthrough to AxisChild. */
       
   682         }
       
   683         case QXmlNodeModelIndex::AxisChild:
       
   684         {
       
   685             QList<QXmlNodeModelIndex> children;
       
   686             QXmlNodeModelIndex child = nextFromSimpleAxis(FirstChild, ni);
       
   687 
       
   688             while(!child.isNull())
       
   689             {
       
   690                 children.append(child);
       
   691                 child = nextFromSimpleAxis(NextSibling, child);
       
   692             }
       
   693 
       
   694             return makeListIterator(children);
       
   695         }
       
   696         case QXmlNodeModelIndex::AxisDescendant:
       
   697         {
       
   698             return makeSequenceMappingIterator<QXmlNodeModelIndex>(this,
       
   699                                                                    ni.iterate(QXmlNodeModelIndex::AxisChild),
       
   700                                                                    DynamicContext::Ptr());
       
   701         }
       
   702         case QXmlNodeModelIndex::AxisAttributeOrTop:
       
   703         {
       
   704             if(kind(ni) == QXmlNodeModelIndex::Attribute && nextFromSimpleAxis(Parent, ni).isNull())
       
   705                 return makeSingletonIterator(ni);
       
   706 
       
   707             /* Else, fallthrough to AxisAttribute. */
       
   708         }
       
   709         case QXmlNodeModelIndex::AxisAttribute:
       
   710             return makeVectorIterator(attributes(ni));
       
   711         case QXmlNodeModelIndex::AxisDescendantOrSelf:
       
   712             return mergeIterators(ni, iterate(ni, QXmlNodeModelIndex::AxisDescendant));
       
   713         case QXmlNodeModelIndex::AxisFollowing:
       
   714         /* Fallthrough. */
       
   715         case QXmlNodeModelIndex::AxisPreceding:
       
   716         {
       
   717             /* We walk up along the ancestors, and for each parent, we grab its preceding/following
       
   718              * siblings, and evaluate the descendant axis. The descendant axes gets added
       
   719              * to a list and we then merge those iterators. */
       
   720             QVector<QXmlNodeModelIndexIteratorPointer> descendantIterators;
       
   721 
       
   722             QXmlNodeModelIndex current(ni);
       
   723             while(!current.isNull())
       
   724             {
       
   725                 QXmlNodeModelIndex candidate(nextFromSimpleAxis(axis == QXmlNodeModelIndex::AxisPreceding ? PreviousSibling : NextSibling, current));
       
   726                 if(candidate.isNull())
       
   727                 {
       
   728                     /* current is an ancestor. We don't want it, so next iteration we
       
   729                      * will grab its preceding sibling. */
       
   730                     current = nextFromSimpleAxis(Parent, current);
       
   731                 }
       
   732                 else
       
   733                 {
       
   734                     current = candidate;
       
   735                     descendantIterators.append(iterate(current, QXmlNodeModelIndex::AxisDescendantOrSelf)->toReversed());
       
   736                 }
       
   737             }
       
   738 
       
   739             return makeSequenceMappingIterator<QXmlNodeModelIndex>(&mergeIterator,
       
   740                                                                    IteratorVector::Ptr(new IteratorVector(descendantIterators)),
       
   741                                                                    DynamicContext::Ptr());
       
   742         }
       
   743     }
       
   744 
       
   745     Q_ASSERT_X(false, Q_FUNC_INFO, "Unknown axis, internal error.");
       
   746     return makeEmptyIterator<QXmlNodeModelIndex>();
       
   747 }
       
   748 
       
   749 /*!
       
   750   \fn QXmlNodeModelIndex QAbstractXmlNodeModel::nextFromSimpleAxis(SimpleAxis axis, const QXmlNodeModelIndex &origin) const
       
   751 
       
   752   When QtXmlPatterns evaluate path expressions, it emulate them through a
       
   753   combination of calls with QSimpleXmlNodeModel::SimpleAxis values. Therefore,
       
   754   the implementation of this function must return the node, if any, that
       
   755   appears on the \a axis emanating from the \a origin.
       
   756 
       
   757   If no such node is available, a default constructed
       
   758   QXmlNodeModelIndex is returned.
       
   759 
       
   760   QSimpleXmlNodeModel eliminates the need to handle redundant corner
       
   761   cases by guaranteeing that it will never ask for:
       
   762 
       
   763   \list
       
   764     \o Children or siblings for attributes.
       
   765     \o Children for comments, processing instructions, and text nodes.
       
   766     \o Siblings or parents for document nodes.
       
   767   \endlist
       
   768 
       
   769   A typical implementation performs a \c switch on the value of \a
       
   770   axis:
       
   771 
       
   772   \code
       
   773   QXmlNodeModelIndex MyTreeModel::nextFromSimpleAxis(SimpleAxis axis, const QXmlNodeModelIndex &origin) const
       
   774   {
       
   775     // Convert the QXmlNodeModelIndex to a value that is specific to what we represent.
       
   776     const MyValue value = toMyValue(ni);
       
   777 
       
   778     switch(axis)
       
   779     {
       
   780         case Parent:
       
   781             return toNodeIndex(value.parent());
       
   782         case FirstChild:
       
   783         case PreviousSibling:
       
   784         case NextSibling:
       
   785             // and so on
       
   786     }
       
   787   }
       
   788   \endcode
       
   789 
       
   790  */
       
   791 
       
   792 /*!
       
   793   \fn QXmlNodeModelIndex QAbstractXmlNodeModel::createIndex(qint64 data) const
       
   794 
       
   795   Creates a node index with \a data as its internal data. \a data is
       
   796   not constrained.
       
   797  */
       
   798 
       
   799 /*!
       
   800   \fn QXmlNodeModelIndex QAbstractXmlNodeModel::createIndex(void *pointer, qint64 additionalData) const
       
   801 
       
   802   Creates a node index with \a pointer and \a additionalData as
       
   803   its internal data.
       
   804 
       
   805   What \a pointer and \a additionalData is, is not constrained.
       
   806  */
       
   807 
       
   808 /*!
       
   809   \fn QXmlNodeModelIndex QAbstractXmlNodeModel::createIndex(qint64 data, qint64 additionalData) const;
       
   810   \overload
       
   811 
       
   812   Creates a QXmlNodeModelIndex containing \a data and \a
       
   813   additionalData.
       
   814  */
       
   815 
       
   816 /*!
       
   817   \fn  QXmlName QAbstractXmlNodeModel::name(const QXmlNodeModelIndex &ni) const
       
   818 
       
   819   Returns the name of \a ni. The caller guarantees that \a ni is not
       
   820   \c null and that it belongs to this QAbstractXmlNodeModel.
       
   821 
       
   822   If a node does not have a name, e.g., comment nodes, a null QXmlName
       
   823   is returned. QXmlNames must be created with the instance of
       
   824   QXmlQuery that is being used for evaluating queries using this
       
   825   QAbstractXmlNodeModel.
       
   826 
       
   827   This function maps to the \c dm:node-name() accessor.
       
   828 
       
   829   If \a ni is a processing instruction, a QXmlName is returned with
       
   830   the local name as the target name and the namespace URI and prefix
       
   831   both empty.
       
   832 
       
   833   \sa {http://www.w3.org/TR/xpath-datamodel/#dm-node-name}{XQuery 1.0 and XPath 2.0 Data Model (XDM), 5.11 node-name Accessor}
       
   834   \sa QXmlName
       
   835  */
       
   836 
       
   837 /*!
       
   838   \fn QVector<QXmlName> QAbstractXmlNodeModel::namespaceBindings(const QXmlNodeModelIndex &n) const
       
   839 
       
   840   Returns the in-scope namespaces of \a n. The caller guarantees that
       
   841   \a n is not \c null and that it belongs to this QAbstractXmlNodeModel.
       
   842 
       
   843   This function corresponds to the \c dm:namespace-nodes accessor.
       
   844 
       
   845   The returned vector of namespace declarations includes namespaces
       
   846   of the ancestors of \a n.
       
   847 
       
   848   The caller guarantees that \a n is an Element that belongs to this
       
   849   QAbstractXmlNodeModel.
       
   850  */
       
   851 
       
   852 /*!
       
   853   \internal
       
   854   Sends the namespaces declared on \a n to \a receiver.
       
   855 
       
   856   As a consequence, no namespaces are sent unless this node is an
       
   857   element and has namespaces declared.
       
   858 
       
   859   The caller guarantees that \a n is not \c null and that it belongs
       
   860   to this QAbstractXmlNodeModel instance.
       
   861 
       
   862   Note that it is not the namespaces that are in scope on \a n, but
       
   863   only the namespaces that are specifically declared on \a n.
       
   864 
       
   865   \a receiver is the receiver that this node is supposed to send its
       
   866   namespaces to. This is guaranteed by the caller to be a valid
       
   867   pointer.  \a n is the index of the node whose namespaces are to
       
   868   be sent.
       
   869  */
       
   870 void QAbstractXmlNodeModel::sendNamespaces(const QXmlNodeModelIndex &n,
       
   871                                            QAbstractXmlReceiver *const receiver) const
       
   872 {
       
   873     Q_ASSERT(receiver);
       
   874     const QVector<QXmlName> nss(namespaceBindings(n));
       
   875 
       
   876     /* This is by far the most common case. */
       
   877     if(nss.isEmpty())
       
   878         return;
       
   879 
       
   880     const int len = nss.size();
       
   881     for(int i = 0; i < len; ++i)
       
   882         receiver->namespaceBinding(nss.at(i));
       
   883 }
       
   884 
       
   885 /*!
       
   886   \fn QString QAbstractXmlNodeModel::stringValue(const QXmlNodeModelIndex &n) const
       
   887 
       
   888   Returns the string value for node \a n.
       
   889 
       
   890   The caller guarantees that \a n is not \c null and that it belong to
       
   891   this QAbstractXmlNodeModel instance.
       
   892 
       
   893   This function maps to the \c dm:string-value() accessor, which the
       
   894   specification completely specifies. Here's a summary:
       
   895 
       
   896   \list
       
   897 
       
   898   \o For processing instructions, the string value is the data
       
   899   section(excluding any whitespace appearing between the name and the
       
   900   data).
       
   901 
       
   902   \o For text nodes, the string value equals the text node.
       
   903 
       
   904   \o For comments, the content of the comment
       
   905 
       
   906   \o For elements, the concatenation of all text nodes that are
       
   907   descendants. Note, this is not only the children, but the
       
   908   childrens' childrens' text nodes, and so forth.
       
   909 
       
   910   \o For document nodes, the concatenation of all text nodes in the
       
   911   document.
       
   912 
       
   913   \endlist
       
   914 
       
   915   \sa {http://www.w3.org/TR/xpath-datamodel/#dm-string-value}{XQuery 1.0 and XPath 2.0 Data Model (XDM), 5.13 string-value Accessor}
       
   916  */
       
   917 
       
   918 /*!
       
   919   \fn QVariant QAbstractXmlNodeModel::typedValue(const QXmlNodeModelIndex &node) const
       
   920 
       
   921   Returns the typed value for node \a node.
       
   922 
       
   923   The typed value is an atomic value, which an element or attribute
       
   924   contains.
       
   925 
       
   926   The caller guarantees that \a node is either an element or an
       
   927   attribute. The implementor guarantees that the returned QVariant has
       
   928   a value which is supported in XQuery. It cannot be an arbitrary
       
   929   QVariant value.  The implementor also guarantees that stringValue()
       
   930   returns a lexical representation of typedValue()(this is guaranteed
       
   931   by QSimpleXmlNodeModel::stringValue()).
       
   932 
       
   933   If the return QVariant is a default constructed variant, it signals
       
   934   that \a node has no typed value.
       
   935 */
       
   936 
       
   937 /*!
       
   938    \internal
       
   939  */
       
   940 QPatternist::ItemIteratorPtr QAbstractXmlNodeModel::sequencedTypedValue(const QXmlNodeModelIndex &ni) const
       
   941 {
       
   942     const QVariant &candidate = typedValue(ni);
       
   943     if(candidate.isNull())
       
   944         return QPatternist::CommonValues::emptyIterator;
       
   945     else
       
   946         return makeSingletonIterator(AtomicValue::toXDM(candidate));
       
   947 }
       
   948 
       
   949 /*!
       
   950  \internal
       
   951  */
       
   952 QPatternist::ItemTypePtr QAbstractXmlNodeModel::type(const QXmlNodeModelIndex &) const
       
   953 {
       
   954     Q_ASSERT_X(false, Q_FUNC_INFO,
       
   955                "This function is internal and must not be called.");
       
   956     return QPatternist::ItemTypePtr();
       
   957 }
       
   958 
       
   959 /*!
       
   960   \internal
       
   961 
       
   962   Returns the namespace URI on \a ni that corresponds to \a prefix.
       
   963 
       
   964   If \a prefix is StandardPrefixes::empty, the namespace URI for the
       
   965   default namespace is returned.
       
   966 
       
   967   The default implementation use namespaceBindings(), in a straight
       
   968   forward manner.
       
   969 
       
   970   If no namespace exists for \a prefix, NamespaceResolver::NoBinding
       
   971   is returned.
       
   972 
       
   973   The caller guarantees to only call this function for element nodes.
       
   974  */
       
   975 QXmlName::NamespaceCode QAbstractXmlNodeModel::namespaceForPrefix(const QXmlNodeModelIndex &ni,
       
   976                                                                   const QXmlName::PrefixCode prefix) const
       
   977 {
       
   978     Q_ASSERT(kind(ni) == QXmlNodeModelIndex::Element);
       
   979 
       
   980     const QVector<QXmlName> nbs(namespaceBindings(ni));
       
   981     const int len = nbs.size();
       
   982 
       
   983     for(int i = 0; i < len; ++i)
       
   984     {
       
   985         if(nbs.at(i).prefix() == prefix)
       
   986             return nbs.at(i).namespaceURI();
       
   987     }
       
   988 
       
   989     return NamespaceResolver::NoBinding;
       
   990 }
       
   991 
       
   992 
       
   993 /*!
       
   994   \internal
       
   995 
       
   996   Determines whether \a ni1 is deep equal to \a ni2.
       
   997 
       
   998   isDeepEqual() is defined as evaluating the expression \c
       
   999   fn:deep-equal($n1, $n2) where \c $n1 is \a ni1 and \c $n1 is \a
       
  1000   ni2. This function is associative, meaning the same value is
       
  1001   returned regardless of if isDeepEqual() is invoked with \a ni1 as
       
  1002   first argument or second. It is guaranteed that \a ni1 and \a ni2
       
  1003   are nodes, as opposed to the definition of \c fn:deep-equal().
       
  1004 
       
  1005   Returns true if \a ni1 is deep-equal to \a ni2, otherwise false
       
  1006 
       
  1007   \sa {"http://www.w3.org/TR/xpath-functions/#func-deep-equal"}{XQuery 1.0 and XPath 2.0 Functions and Operators, 15.3.1 fn:deep-equal}
       
  1008  */
       
  1009 bool QAbstractXmlNodeModel::isDeepEqual(const QXmlNodeModelIndex &n1,
       
  1010                                         const QXmlNodeModelIndex &n2) const
       
  1011 {
       
  1012     Q_ASSERT(!n1.isNull());
       
  1013     Q_ASSERT(!n2.isNull());
       
  1014 
       
  1015     const QXmlNodeModelIndex::NodeKind nk = n1.kind();
       
  1016 
       
  1017     if(nk != n2.kind())
       
  1018         return false;
       
  1019 
       
  1020     if(n1.name() != n2.name())
       
  1021         return false;
       
  1022 
       
  1023     switch(nk)
       
  1024     {
       
  1025         case QXmlNodeModelIndex::Element:
       
  1026         {
       
  1027             QXmlNodeModelIndexIteratorPointer atts1(n1.iterate(QXmlNodeModelIndex::AxisAttribute));
       
  1028             QXmlNodeModelIndex node(atts1->next());
       
  1029 
       
  1030             const QXmlNodeModelIndex::List atts2(n2.iterate(QXmlNodeModelIndex::AxisAttribute)->toList());
       
  1031             const QXmlNodeModelIndex::List::const_iterator end(atts2.constEnd());
       
  1032 
       
  1033             while(!node.isNull())
       
  1034             {
       
  1035                 bool equal = false;
       
  1036                 for(QXmlNodeModelIndex::List::const_iterator it = atts2.constBegin(); it != end; ++it)
       
  1037                 {
       
  1038                     if(isDeepEqual(node, (*it)))
       
  1039                         equal = true;
       
  1040                 }
       
  1041 
       
  1042                 if(!equal)
       
  1043                     return false;
       
  1044 
       
  1045                 node = atts1->next();
       
  1046             }
       
  1047 
       
  1048             /* Fallthrough, so we check the children. */
       
  1049         }
       
  1050         case QXmlNodeModelIndex::Document:
       
  1051         {
       
  1052             QXmlNodeModelIndexIteratorPointer itn1(n1.iterate(QXmlNodeModelIndex::AxisChild));
       
  1053             QXmlNodeModelIndexIteratorPointer itn2(n2.iterate(QXmlNodeModelIndex::AxisChild));
       
  1054 
       
  1055             while(true)
       
  1056             {
       
  1057                 QXmlNodeModelIndex no1(itn1->next());
       
  1058                 QXmlNodeModelIndex no2(itn2->next());
       
  1059 
       
  1060                 while(!no1.isNull() && isIgnorableInDeepEqual(no1))
       
  1061                     no1 = itn1->next();
       
  1062 
       
  1063                 while(!no2.isNull() && isIgnorableInDeepEqual(no2))
       
  1064                     no2 = itn2->next();
       
  1065 
       
  1066                 if(!no1.isNull() && !no2.isNull())
       
  1067                 {
       
  1068                    if(!isDeepEqual(no1, no2))
       
  1069                        return false;
       
  1070                 }
       
  1071                 else
       
  1072                     return no1.isNull() && no2.isNull();
       
  1073             }
       
  1074 
       
  1075             return true;
       
  1076         }
       
  1077         case QXmlNodeModelIndex::Attribute:
       
  1078         /* Fallthrough */
       
  1079         case QXmlNodeModelIndex::ProcessingInstruction:
       
  1080         /* Fallthrough. */
       
  1081         case QXmlNodeModelIndex::Text:
       
  1082         /* Fallthrough. */
       
  1083         case QXmlNodeModelIndex::Comment:
       
  1084             return n1.stringValue() == n2.stringValue();
       
  1085         case QXmlNodeModelIndex::Namespace:
       
  1086         {
       
  1087             Q_ASSERT_X(false, Q_FUNC_INFO, "Not implemented");
       
  1088             return false;
       
  1089         }
       
  1090     }
       
  1091 
       
  1092     return false;
       
  1093 }
       
  1094 
       
  1095 /*!
       
  1096   \class QXmlItem
       
  1097   \reentrant
       
  1098   \since 4.4
       
  1099   \brief The QXmlItem class contains either an XML node or an atomic value.
       
  1100   \ingroup xml-tools
       
  1101 
       
  1102   In XQuery, all expressions evaluate to a sequence of items, where
       
  1103   each item is either an XML node or an atomic value. The query in the
       
  1104   following snippet evaluates to sequence of five items.
       
  1105 
       
  1106   \quotefile doc/src/snippets/patternist/items.xq
       
  1107 
       
  1108   The five items are: An element, an atomic value (binary data encoded
       
  1109   in base64), a date, a float, and an attribute.
       
  1110 
       
  1111   QXmlItem is the class that represents these XQuery items in the
       
  1112   QtXmlPatterns API. A non-null instance of QXmlItem is either a node
       
  1113   or an atomic value. Calling isNode() or isAtomicValue() tells you
       
  1114   which it is. Atomic values are represented elsewhere in the Qt API
       
  1115   as instances of QVariant, and an instance of QXmlItem that
       
  1116   represents an atomic value can be converted to a QVariant by calling
       
  1117   toAtomicValue(). A QXmlItem that wraps a node is represented
       
  1118   elsewhere as an instance of QXmlNodeModelIndex. A node QXmlItem can
       
  1119   be converted to a QXmlNodeModelIndex by calling toNodeModelIndex().
       
  1120 
       
  1121   A default constructed QXmlItem instance is neither a node nor an
       
  1122   atomic value. It is considered null, in which case isNull() returns
       
  1123   true.
       
  1124 
       
  1125   An instance of QXmlItem will be left dangling if the
       
  1126   \l{QAbstractXmlNodeModel} {XML node model} it
       
  1127   refers to is deleted, if it is a QXmlNodeModelIndex.
       
  1128  */
       
  1129 
       
  1130 /*!
       
  1131   \typedef QXmlItem::Iterator
       
  1132   A QAbstractXmlForwardIterator over QXmlItem.
       
  1133  */
       
  1134 
       
  1135 /*!
       
  1136   Constructs a null QXmlItem that is neither a node nor an atomic
       
  1137   value. isNull() returns true for a default constructed instance.
       
  1138  */
       
  1139 QXmlItem::QXmlItem()
       
  1140 {
       
  1141     m_node.model = 0;
       
  1142     m_node.data = 0;
       
  1143     m_node.additionalData = 0;
       
  1144 }
       
  1145 
       
  1146 bool QXmlItem::internalIsAtomicValue() const
       
  1147 {
       
  1148     return m_node.model == reinterpret_cast<QAbstractXmlNodeModel *>(~0);
       
  1149 }
       
  1150 
       
  1151 /*!
       
  1152   The copy constructor constructs a copy of \a other.
       
  1153  */
       
  1154 QXmlItem::QXmlItem(const QXmlItem &other) : m_node(other.m_node)
       
  1155 {
       
  1156     if(internalIsAtomicValue())
       
  1157         m_atomicValue->ref.ref();
       
  1158 }
       
  1159 
       
  1160 /*!
       
  1161   Constructs an atomic value QXmlItem with \a atomicValue.
       
  1162 
       
  1163   \sa isAtomicValue()
       
  1164  */
       
  1165 QXmlItem::QXmlItem(const QVariant &atomicValue)
       
  1166 {
       
  1167     if(atomicValue.isNull())
       
  1168     {
       
  1169         /* Then we behave just like the default constructor. */
       
  1170         m_node.model = 0;
       
  1171         m_node.data = 0;
       
  1172         m_node.additionalData = 0;
       
  1173         return;
       
  1174     }
       
  1175 
       
  1176     /*
       
  1177       We can't assign directly to m_atomicValue, because the
       
  1178       temporary will self-destruct before we've ref'd it.
       
  1179     */
       
  1180     const QPatternist::Item temp(QPatternist::AtomicValue::toXDM(atomicValue));
       
  1181 
       
  1182     if(temp)
       
  1183     {
       
  1184         temp.asAtomicValue()->ref.ref();
       
  1185         m_node.model = reinterpret_cast<const QAbstractXmlNodeModel *>(~0);
       
  1186         m_atomicValue = temp.asAtomicValue();
       
  1187     }
       
  1188     else
       
  1189     {
       
  1190         m_atomicValue = 0;
       
  1191         m_node.model = 0;
       
  1192     }
       
  1193 
       
  1194     m_node.additionalData = 0;
       
  1195 }
       
  1196 
       
  1197 /*!
       
  1198   Constructs a node QXmlItem that is a copy of \a node.
       
  1199 
       
  1200   \sa isNode()
       
  1201  */
       
  1202 QXmlItem::QXmlItem(const QXmlNodeModelIndex &node) : m_node(node.m_storage)
       
  1203 {
       
  1204 }
       
  1205 
       
  1206 
       
  1207 /*!
       
  1208   Destructor.
       
  1209  */
       
  1210 QXmlItem::~QXmlItem()
       
  1211 {
       
  1212     if(internalIsAtomicValue() && !m_atomicValue->ref.deref())
       
  1213         delete m_atomicValue;
       
  1214 }
       
  1215 
       
  1216 bool QPatternist::NodeIndexStorage::operator!=(const NodeIndexStorage &other) const
       
  1217 {
       
  1218     return data != other.data
       
  1219            || additionalData != other.additionalData
       
  1220            || model != other.model;
       
  1221 }
       
  1222 
       
  1223 /*!
       
  1224   Assigns \a other to \c this.
       
  1225  */
       
  1226 QXmlItem &QXmlItem::operator=(const QXmlItem &other)
       
  1227 {
       
  1228     if(m_node != other.m_node)
       
  1229     {
       
  1230         if(internalIsAtomicValue() && !m_atomicValue->ref.deref())
       
  1231             delete m_atomicValue;
       
  1232 
       
  1233         m_node = other.m_node;
       
  1234 
       
  1235         if(internalIsAtomicValue())
       
  1236             m_atomicValue->ref.ref();
       
  1237     }
       
  1238 
       
  1239     return *this;
       
  1240 }
       
  1241 
       
  1242 /*!
       
  1243   Returns true if this item is a Node. Returns false if it
       
  1244   is an atomic value or null.
       
  1245 
       
  1246   \sa isNull(), isAtomicValue()
       
  1247  */
       
  1248 bool QXmlItem::isNode() const
       
  1249 {
       
  1250     return QPatternist::Item::fromPublic(*this).isNode();
       
  1251 }
       
  1252 
       
  1253 /*!
       
  1254   Returns true if this item is an atomic value. Returns false
       
  1255   if it is a node or null.
       
  1256 
       
  1257   \sa isNull(), isNode()
       
  1258  */
       
  1259 bool QXmlItem::isAtomicValue() const
       
  1260 {
       
  1261     return internalIsAtomicValue();
       
  1262 }
       
  1263 
       
  1264 /*!
       
  1265   If this QXmlItem represents an atomic value, it is converted
       
  1266   to an appropriate QVariant and returned. If this QXmlItem is
       
  1267   not an atomic value, the return value is a default constructed
       
  1268   QVariant. You can call isAtomicValue() to test whether the
       
  1269   item is an atomic value.
       
  1270 
       
  1271  \sa isAtomicValue()
       
  1272  */
       
  1273 QVariant QXmlItem::toAtomicValue() const
       
  1274 {
       
  1275     if(isAtomicValue())
       
  1276         return QPatternist::AtomicValue::toQt(m_atomicValue);
       
  1277     else
       
  1278         return QVariant();
       
  1279 }
       
  1280 
       
  1281 /*!
       
  1282   If this QXmlItem represents a node, it returns the item as a
       
  1283   QXmlNodeModelIndex. If this QXmlItem is not a node, the return
       
  1284   value is undefined. You can call isNode() to test whether the
       
  1285   item is a node.
       
  1286 
       
  1287  \sa isNode()
       
  1288  */
       
  1289 QXmlNodeModelIndex QXmlItem::toNodeModelIndex() const
       
  1290 {
       
  1291     if(isNode())
       
  1292         return reinterpret_cast<const QXmlNodeModelIndex &>(m_node);
       
  1293     else
       
  1294         return QXmlNodeModelIndex();
       
  1295 }
       
  1296 
       
  1297 /*!
       
  1298   Returns true if this QXmlItem is neither a node nor an
       
  1299   atomic value. Default constructed instances of QXmlItem
       
  1300   are null.
       
  1301  */
       
  1302 bool QXmlItem::isNull() const
       
  1303 {
       
  1304     return !m_node.model;
       
  1305 }
       
  1306 
       
  1307 /*!
       
  1308   \class QXmlNodeModelIndex
       
  1309   \brief The QXmlNodeModelIndex class identifies a node in an XML node model subclassed from QAbstractXmlNodeModel.
       
  1310   \reentrant
       
  1311   \since 4.4
       
  1312   \ingroup xml-tools
       
  1313 
       
  1314   QXmlNodeModelIndex is an index into an \l{QAbstractXmlNodeModel}
       
  1315   {XML node model}. It contains:
       
  1316 
       
  1317   \list
       
  1318     \o A pointer to an \l{QAbstractXmlNodeModel} {XML node model},
       
  1319     which is returned by model(), and
       
  1320     \o Some data, which is returned by data(), internalPointer(),
       
  1321     and additionalData().
       
  1322   \endlist
       
  1323 
       
  1324   Because QXmlNodeModelIndex is intentionally a simple class, it
       
  1325   doesn't have member functions for accessing the properties of
       
  1326   nodes. For example, it doesn't have functions for getting a
       
  1327   node's name or its list of attributes or child nodes. If you find
       
  1328   that you need to retrieve this kind of information from your
       
  1329   query results, there are two ways to proceed.
       
  1330 
       
  1331   \list
       
  1332 
       
  1333   \o Send the output of your XQuery to an \l{QAbstractXmlReceiver}
       
  1334   {XML receiver}, or
       
  1335 
       
  1336   \o Let your XQuery do all the work to produce the desired result.
       
  1337 
       
  1338   \endlist
       
  1339 
       
  1340   The second case is explained by example. Suppose you want to
       
  1341   populate a list widget with the values of certain attributes from a
       
  1342   set of result elements. You could write an XQuery to return the set
       
  1343   of elements, and then you would write the code to iterate over the
       
  1344   result elements, get their attributes, and extract the desired
       
  1345   string values. But the simpler way is to just augment your XQuery to
       
  1346   finding the desired attribute values. Then all you have to do is
       
  1347   evaluate the XQuery using the version of QXmlQuery::evaluateTo()
       
  1348   that populates a QStringList, which you can send directly to your
       
  1349   widget.
       
  1350 
       
  1351   QXmlNodeModelIndex doesn't impose any restrictions on the \c data
       
  1352   value an QXmlNodeModelIndex should contain. The meaning of the data
       
  1353   left to the associated \l {QAbstractXmlNodeModel} {node model}.
       
  1354   Because QXmlNodeModelIndex depends on a particular subclass of
       
  1355   QAbstractXmlNodeModel for its existence, the only way you can create
       
  1356   an instance of QXmlNodeModelIndex is by asking the node model to
       
  1357   create one for you with QAbstractXmlNodeModel::createIndex(). Since
       
  1358   that function is protected, it is usually a good ide to write a
       
  1359   public function that creates a QXmlNodeModelIndex from arguments that
       
  1360   are appropriate for your particular node model.
       
  1361 
       
  1362   A default constructed node index is said to be null, i.e., isNull()
       
  1363   returns true.
       
  1364 
       
  1365   QXmlNodeModelIndex and QAbstractXmlNodeModel follow the same design
       
  1366   pattern used for QModelIndex and QAbstractItemModel.
       
  1367  */
       
  1368 
       
  1369 /*!
       
  1370   \since 4.4
       
  1371   \relates QHash
       
  1372 
       
  1373   Computes a hash key from the QXmlNodeModelIndex \a index, and
       
  1374   returns it. This function would be used by QHash if you wanted
       
  1375   to build a hash table for instances of QXmlNodeModelIndex.
       
  1376 
       
  1377   The hash is computed on QXmlNodeModelIndex::data(),
       
  1378   QXmlNodeModelIndex::additionalData(), and
       
  1379   QXmlNodeModelIndex::model(). This means the hash key can be used for
       
  1380   node indexes from different node models.
       
  1381  */
       
  1382 uint qHash(const QXmlNodeModelIndex &index)
       
  1383 {
       
  1384     return uint(index.data() + index.additionalData() + quintptr(index.model()));
       
  1385 }
       
  1386 
       
  1387 /*!
       
  1388   \enum QXmlNodeModelIndex::NodeKind
       
  1389 
       
  1390   Identifies a kind of node.
       
  1391 
       
  1392   \value Attribute Identifies an attribute node
       
  1393   \value Text Identifies a text node
       
  1394   \value Comment Identifies a comment node
       
  1395   \value Document Identifies a document node
       
  1396   \value Element Identifies an element node
       
  1397   \value Namespace Identifies a namespace node
       
  1398   \value ProcessingInstruction Identifies a processing instruction.
       
  1399 
       
  1400   Note that the optional XML declaration at very beginning of the XML
       
  1401   document is not a processing instruction
       
  1402 
       
  1403   \sa QAbstractXmlNodeModel::kind()
       
  1404 */
       
  1405 
       
  1406 /*!
       
  1407  \typedef QXmlNodeModelIndex::List
       
  1408 
       
  1409  Typedef for QList<QXmlNodeModelIndex>.
       
  1410  */
       
  1411 
       
  1412 /*!
       
  1413   Returns true if this node is the same as \a other. This operator
       
  1414   does not compare values, children, or names of nodes. It compares
       
  1415   node identities, i.e., whether two nodes are from the same document
       
  1416   and are found at the exact same place.
       
  1417  */
       
  1418 bool QXmlNodeModelIndex::operator==(const QXmlNodeModelIndex &other) const
       
  1419 {
       
  1420     return !(m_storage != other.m_storage);
       
  1421 }
       
  1422 
       
  1423 /*!
       
  1424   Returns true if \a other is the same node as this.
       
  1425  */
       
  1426 bool QXmlNodeModelIndex::operator!=(const QXmlNodeModelIndex &other) const
       
  1427 {
       
  1428     return !(operator==(other));
       
  1429 }
       
  1430 
       
  1431 /*!
       
  1432  \fn QXmlNodeModelIndex::QXmlNodeModelIndex()
       
  1433 
       
  1434  Default constructor. Creates an item that is \c null.
       
  1435 
       
  1436  \sa isNull()
       
  1437  */
       
  1438 
       
  1439 /*!
       
  1440  \fn QXmlNodeModelIndex::QXmlNodeModelIndex(const QXmlNodeModelIndex &other)
       
  1441 
       
  1442  Standard copy constructor. Creates a QXmlNodeModelIndex instance that
       
  1443  is a copy of \a other.
       
  1444  */
       
  1445 
       
  1446 /*!
       
  1447  \fn bool QXmlNodeModelIndex::isNull() const
       
  1448 
       
  1449  Returns true if this QXmlNodeModelIndex is a default constructed
       
  1450  value, otherwise false.
       
  1451 
       
  1452  A null QXmlNodeModelIndex doesn't represent any node and cannot
       
  1453  be used in conjunction with QAbstractXmlNodeModel.
       
  1454  */
       
  1455 
       
  1456 /*!
       
  1457  \fn const QAbstractXmlNodeModel *QXmlNodeModelIndex::model() const
       
  1458 
       
  1459  Returns the QAbstractXmlNodeModel that this node index refers to.
       
  1460  QXmlNodeModelIndex does not own QAbstractXmlNodeModel and does not
       
  1461  keep track of its lifetime, so this pointer will dangle if the
       
  1462  QAbstractXmlNodeModel is deallocated first.
       
  1463 
       
  1464  There is no setter for the node model because instances of
       
  1465  QXmlNodeModelIndex instances are only created with
       
  1466  QAbstractXmlNodeModel::createIndex().
       
  1467 */
       
  1468 
       
  1469 /*!
       
  1470  \fn qint64 QXmlNodeModelIndex::data() const
       
  1471 
       
  1472  Returns the first data value. The node index holds two data values.
       
  1473  additionalData() returns the second one.
       
  1474 
       
  1475  \sa additionalData()
       
  1476 */
       
  1477 
       
  1478 /*!
       
  1479  \fn void *QXmlNodeModelIndex::internalPointer() const
       
  1480 
       
  1481  Returns the first data value as a void* pointer.
       
  1482 
       
  1483  \sa additionalData()
       
  1484 */
       
  1485 
       
  1486 /*!
       
  1487  \fn qint64 QXmlNodeModelIndex::additionalData() const
       
  1488 
       
  1489  Returns the second data value. The node index holds two data values.
       
  1490  data() returns the first one.
       
  1491 
       
  1492  \sa data()
       
  1493 */
       
  1494 
       
  1495 /*!
       
  1496  \fn void QXmlNodeModelIndex::reset()
       
  1497  \internal
       
  1498 
       
  1499  Resets this QXmlNodeModelIndex to be null. It is equivalent to
       
  1500  writing:
       
  1501 
       
  1502  \snippet doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlnodemodel.cpp 0
       
  1503  */
       
  1504 
       
  1505 /*!
       
  1506  \fn QXmlName QXmlNodeModelIndex::name() const
       
  1507  \internal
       
  1508 */
       
  1509 
       
  1510 /*!
       
  1511  \typedef QXmlNodeModelIndex::Iterator
       
  1512  \internal
       
  1513 
       
  1514  Typedef for QAbstractXmlForwardIterator<QXmlNodeModelIndex>.
       
  1515  */
       
  1516 /*!
       
  1517  \fn QXmlNodeModelIndex QXmlNodeModelIndex::root() const
       
  1518  \internal
       
  1519 */
       
  1520 
       
  1521 /*!
       
  1522  \fn QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QXmlNodeModelIndex> > QXmlNodeModelIndex::iterate(const Axis axis) const
       
  1523  \internal
       
  1524 */
       
  1525 
       
  1526 /*!
       
  1527  \fn QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QPatternist::Item> > QXmlNodeModelIndex::sequencedTypedValue() const
       
  1528  \internal
       
  1529 */
       
  1530 
       
  1531 /*!
       
  1532  \fn QUrl QXmlNodeModelIndex::documentUri() const
       
  1533  \internal
       
  1534 */
       
  1535 
       
  1536 /*!
       
  1537  \fn QUrl QXmlNodeModelIndex::baseUri() const
       
  1538  \internal
       
  1539 */
       
  1540 
       
  1541 /*!
       
  1542  \fn NodeKind QXmlNodeModelIndex::kind() const
       
  1543  \internal
       
  1544 */
       
  1545 
       
  1546 /*!
       
  1547  \fn bool QXmlNodeModelIndex::isDeepEqual(const QXmlNodeModelIndex &other) const
       
  1548  \internal
       
  1549 */
       
  1550 
       
  1551 /*!
       
  1552  \fn DocumentOrder QXmlNodeModelIndex::compareOrder(const QXmlNodeModelIndex &other) const
       
  1553  \internal
       
  1554 */
       
  1555 
       
  1556 /*!
       
  1557  \fn void QXmlNodeModelIndex::sendNamespaces(QAbstractXmlReceiver *const receiver) const
       
  1558  \internal
       
  1559 */
       
  1560 
       
  1561 /*!
       
  1562  \fn QVector<QXmlName> QXmlNodeModelIndex::namespaceBindings() const
       
  1563  \internal
       
  1564 */
       
  1565 
       
  1566 /*!
       
  1567  \fn QXmlNodeModelIndex QAbstractXmlNodeModel::elementById(const QXmlName &id) const
       
  1568 
       
  1569  Returns the index of the element identified as \a id. XQuery's \c
       
  1570  id() function calls this function.
       
  1571 
       
  1572  The node index returned will be the element node whose value is of
       
  1573  type \c ID and equals \a id, or it will be the element node that has
       
  1574  an attribute whose typed value is of type \c ID and equals \a id. If
       
  1575  there is no such element, a default constructed QXmlNodeModelIndex
       
  1576  instance is returned. The implementor guarantees that if the returned
       
  1577  node index is not null, it identifies an element.
       
  1578 
       
  1579  It is not sufficient for an attribute or element to merely be called
       
  1580  \c id. Its value type must also be \c ID. However, the reserved name
       
  1581  \c xml:id is sufficient.
       
  1582 
       
  1583  In \a id, the \c{namespace URI} and the \c{prefix} are undefined, and
       
  1584  the \c{local name} is the ID that should be looked up.
       
  1585 
       
  1586  \sa {http://www.w3.org/TR/xpath-functions/#func-id}{XQuery 1.0 and XPath 2.0 Functions and Operators, 15.5.2 fn:id}
       
  1587  */
       
  1588 
       
  1589 /*!
       
  1590  \fn QVector<QXmlNodeModelIndex> QAbstractXmlNodeModel::nodesByIdref(const QXmlName &idref) const
       
  1591 
       
  1592  Returns the elements and/or attributes that have an \c IDREF value
       
  1593  equal to \a idref. XQuery's \c idref() function calls this function.
       
  1594 
       
  1595  The implementor guarantees that the nodes identified by the returned
       
  1596  indexes are elements or attributes.
       
  1597 
       
  1598  It is not sufficient for an attribute or element to merely be called
       
  1599  \c idref. It must also be of type \c IDREF. Elements must be typed as
       
  1600  \c xs:IDREF or \c xs:IDREFS, or, in the case of attributes, as \c
       
  1601  IDREF or \c IDREFS in the schema.
       
  1602 
       
  1603  In \a idref, the \c{namespace URI} and the \c{prefix} are undefined,
       
  1604  and the \c{local name} is the ID that should be looked up.
       
  1605 
       
  1606  \sa {http://www.w3.org/TR/xpath-functions/#func-idref}{XQuery 1.0 and XPath 2.0 Functions and Operators, 15.5.3 fn:idref}
       
  1607  */
       
  1608 
       
  1609 /*!
       
  1610  \fn QXmlName::NamespaceCode QXmlNodeModelIndex::namespaceForPrefix(const QXmlName::PrefixCode prefix) const
       
  1611  \internal
       
  1612 */
       
  1613 
       
  1614 /*!
       
  1615  \fn QString QXmlNodeModelIndex::stringValue() const
       
  1616  \internal
       
  1617 */
       
  1618 
       
  1619 /*!
       
  1620  \fn QPatternist::ItemTypePtr QXmlNodeModelIndex::type() const
       
  1621  \internal
       
  1622 */
       
  1623 
       
  1624 /*!
       
  1625  \fn bool QXmlNodeModelIndex::is(const QXmlNodeModelIndex &other) const
       
  1626  \internal
       
  1627 */
       
  1628 
       
  1629 /*!
       
  1630  \enum QAbstractXmlNodeModel::NodeCopySetting
       
  1631  \internal
       
  1632 
       
  1633  Controls how nodes are copied with copyNodeTo.
       
  1634 
       
  1635  \value InheritNamespaces Copies the node with the \c copy-namespaces
       
  1636         setting being \c inherit. If not set, \c no-inherit is assumed.
       
  1637  \value PreserveNamespaces Copies the node with the \c copy-namespaces
       
  1638         settings being \c preserve. If not set, \c no-preserve is assumed.
       
  1639  */
       
  1640 
       
  1641 /*!
       
  1642  \typedef QAbstractXmlNodeModel::NodeCopySettings
       
  1643  \internal
       
  1644  */
       
  1645 
       
  1646 /*!
       
  1647  \internal
       
  1648 
       
  1649  Copies node \a node to \a receiver, steered by \a copySettings.
       
  1650 
       
  1651  The caller guarantees that \a node is not \c null, and that is
       
  1652  belongs to this QAbstractXmlNodeModel instance.
       
  1653 
       
  1654  The caller guarantees that \a receiver is not \c null.
       
  1655 */
       
  1656 void QAbstractXmlNodeModel::copyNodeTo(const QXmlNodeModelIndex &node,
       
  1657                                        QAbstractXmlReceiver *const receiver,
       
  1658                                        const NodeCopySettings &copySettings) const
       
  1659 {
       
  1660     Q_UNUSED(node);
       
  1661     Q_UNUSED(receiver);
       
  1662     Q_UNUSED(copySettings);
       
  1663     Q_ASSERT_X(false, Q_FUNC_INFO,
       
  1664                "This function is not expected to be called.");
       
  1665 }
       
  1666 
       
  1667 /*!
       
  1668     Returns the source location for the object with the given \a index
       
  1669     or a default constructed QSourceLocation in case no location
       
  1670     information is available.
       
  1671 
       
  1672     \since 4.6
       
  1673 */
       
  1674 QSourceLocation QAbstractXmlNodeModel::sourceLocation(const QXmlNodeModelIndex &index) const
       
  1675 {
       
  1676     // TODO: make this method virtual in Qt5 to allow source location support in custom models
       
  1677     if (d_ptr)
       
  1678         return d_ptr->sourceLocation(index);
       
  1679     else
       
  1680         return QSourceLocation();
       
  1681 }
       
  1682 
       
  1683 QT_END_NAMESPACE