bc1d2a8918c95e8c891447a6c123b6492b7aba49
[profile/ivi/qtxmlpatterns.git] / src / xmlpatterns / api / qabstractxmlnodemodel.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtXmlPatterns module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
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     \li Instantiate QXmlQuery and give it the XQuery to be run;
165
166     \li Instantiate a subclass of QAbstractXmlNodeModel or
167     QSimpleXmlNodeModel;
168
169     \li Retrieve a QXmlNodeModelIndex for the node in the model where
170     the QXmlQuery should start the query;
171
172     \li Use QXmlQuery::bindVariable() to bind the QXmlNodeModelIndex
173     to \c {$variable name};
174
175     \li 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   \li For document nodes, the base URI and the document URI are the same.
343
344   \li 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   \li Namespace nodes have no base URI.
349
350   \li 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   \li 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   \li 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     \li Children or siblings for attributes.
765     \li Children for comments, processing instructions, and text nodes.
766     \li 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   \li For processing instructions, the string value is the data
899   section(excluding any whitespace appearing between the name and the
900   data).
901
902   \li For text nodes, the string value equals the text node.
903
904   \li For comments, the content of the comment
905
906   \li 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   \li 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.reset();
1142 }
1143
1144 bool QXmlItem::internalIsAtomicValue() const
1145 {
1146     return m_node.model == reinterpret_cast<QAbstractXmlNodeModel *>(~0);
1147 }
1148
1149 /*!
1150   The copy constructor constructs a copy of \a other.
1151  */
1152 QXmlItem::QXmlItem(const QXmlItem &other) : m_node(other.m_node)
1153 {
1154     if(internalIsAtomicValue())
1155         m_atomicValue->ref.ref();
1156 }
1157
1158 /*!
1159   Constructs an atomic value QXmlItem with \a atomicValue.
1160
1161   \sa isAtomicValue()
1162  */
1163 QXmlItem::QXmlItem(const QVariant &atomicValue)
1164 {
1165     m_node.reset();
1166     if(atomicValue.isNull())
1167     {
1168         /* Then we behave just like the default constructor. */
1169         return;
1170     }
1171
1172     /*
1173       We can't assign directly to m_atomicValue, because the
1174       temporary will self-destruct before we've ref'd it.
1175     */
1176     const QPatternist::Item temp(QPatternist::AtomicValue::toXDM(atomicValue));
1177
1178     if(temp)
1179     {
1180         temp.asAtomicValue()->ref.ref();
1181         m_node.model = reinterpret_cast<const QAbstractXmlNodeModel *>(~0);
1182         m_atomicValue = temp.asAtomicValue();
1183     }
1184     else
1185     {
1186         m_atomicValue = 0;
1187     }
1188 }
1189
1190 /*!
1191   Constructs a node QXmlItem that is a copy of \a node.
1192
1193   \sa isNode()
1194  */
1195 QXmlItem::QXmlItem(const QXmlNodeModelIndex &node) : m_node(node.m_storage)
1196 {
1197 }
1198
1199
1200 /*!
1201   Destructor.
1202  */
1203 QXmlItem::~QXmlItem()
1204 {
1205     if(internalIsAtomicValue() && !m_atomicValue->ref.deref())
1206         delete m_atomicValue;
1207 }
1208
1209 bool QPatternist::NodeIndexStorage::operator!=(const NodeIndexStorage &other) const
1210 {
1211     return data != other.data
1212            || additionalData != other.additionalData
1213            || model != other.model;
1214 }
1215
1216 /*!
1217   Assigns \a other to \c this.
1218  */
1219 QXmlItem &QXmlItem::operator=(const QXmlItem &other)
1220 {
1221     if(m_node != other.m_node)
1222     {
1223         if(internalIsAtomicValue() && !m_atomicValue->ref.deref())
1224             delete m_atomicValue;
1225
1226         m_node = other.m_node;
1227
1228         if(internalIsAtomicValue())
1229             m_atomicValue->ref.ref();
1230     }
1231
1232     return *this;
1233 }
1234
1235 /*!
1236   Returns true if this item is a Node. Returns false if it
1237   is an atomic value or null.
1238
1239   \sa isNull(), isAtomicValue()
1240  */
1241 bool QXmlItem::isNode() const
1242 {
1243     return QPatternist::Item::fromPublic(*this).isNode();
1244 }
1245
1246 /*!
1247   Returns true if this item is an atomic value. Returns false
1248   if it is a node or null.
1249
1250   \sa isNull(), isNode()
1251  */
1252 bool QXmlItem::isAtomicValue() const
1253 {
1254     return internalIsAtomicValue();
1255 }
1256
1257 /*!
1258   If this QXmlItem represents an atomic value, it is converted
1259   to an appropriate QVariant and returned. If this QXmlItem is
1260   not an atomic value, the return value is a default constructed
1261   QVariant. You can call isAtomicValue() to test whether the
1262   item is an atomic value.
1263
1264  \sa isAtomicValue()
1265  */
1266 QVariant QXmlItem::toAtomicValue() const
1267 {
1268     if(isAtomicValue())
1269         return QPatternist::AtomicValue::toQt(m_atomicValue);
1270     else
1271         return QVariant();
1272 }
1273
1274 /*!
1275   If this QXmlItem represents a node, it returns the item as a
1276   QXmlNodeModelIndex. If this QXmlItem is not a node, the return
1277   value is undefined. You can call isNode() to test whether the
1278   item is a node.
1279
1280  \sa isNode()
1281  */
1282 QXmlNodeModelIndex QXmlItem::toNodeModelIndex() const
1283 {
1284     if(isNode())
1285         return reinterpret_cast<const QXmlNodeModelIndex &>(m_node);
1286     else
1287         return QXmlNodeModelIndex();
1288 }
1289
1290 /*!
1291   Returns true if this QXmlItem is neither a node nor an
1292   atomic value. Default constructed instances of QXmlItem
1293   are null.
1294  */
1295 bool QXmlItem::isNull() const
1296 {
1297     return !m_node.model;
1298 }
1299
1300 /*!
1301   \class QXmlNodeModelIndex
1302   \brief The QXmlNodeModelIndex class identifies a node in an XML node model subclassed from QAbstractXmlNodeModel.
1303   \reentrant
1304   \since 4.4
1305   \ingroup xml-tools
1306
1307   QXmlNodeModelIndex is an index into an \l{QAbstractXmlNodeModel}
1308   {XML node model}. It contains:
1309
1310   \list
1311     \li A pointer to an \l{QAbstractXmlNodeModel} {XML node model},
1312     which is returned by model(), and
1313     \li Some data, which is returned by data(), internalPointer(),
1314     and additionalData().
1315   \endlist
1316
1317   Because QXmlNodeModelIndex is intentionally a simple class, it
1318   doesn't have member functions for accessing the properties of
1319   nodes. For example, it doesn't have functions for getting a
1320   node's name or its list of attributes or child nodes. If you find
1321   that you need to retrieve this kind of information from your
1322   query results, there are two ways to proceed.
1323
1324   \list
1325
1326   \li Send the output of your XQuery to an \l{QAbstractXmlReceiver}
1327   {XML receiver}, or
1328
1329   \li Let your XQuery do all the work to produce the desired result.
1330
1331   \endlist
1332
1333   The second case is explained by example. Suppose you want to
1334   populate a list widget with the values of certain attributes from a
1335   set of result elements. You could write an XQuery to return the set
1336   of elements, and then you would write the code to iterate over the
1337   result elements, get their attributes, and extract the desired
1338   string values. But the simpler way is to just augment your XQuery to
1339   finding the desired attribute values. Then all you have to do is
1340   evaluate the XQuery using the version of QXmlQuery::evaluateTo()
1341   that populates a QStringList, which you can send directly to your
1342   widget.
1343
1344   QXmlNodeModelIndex doesn't impose any restrictions on the \c data
1345   value an QXmlNodeModelIndex should contain. The meaning of the data
1346   left to the associated \l {QAbstractXmlNodeModel} {node model}.
1347   Because QXmlNodeModelIndex depends on a particular subclass of
1348   QAbstractXmlNodeModel for its existence, the only way you can create
1349   an instance of QXmlNodeModelIndex is by asking the node model to
1350   create one for you with QAbstractXmlNodeModel::createIndex(). Since
1351   that function is protected, it is usually a good idea to write a
1352   public function that creates a QXmlNodeModelIndex from arguments that
1353   are appropriate for your particular node model.
1354
1355   A default constructed node index is said to be null, i.e., isNull()
1356   returns true.
1357
1358   QXmlNodeModelIndex and QAbstractXmlNodeModel follow the same design
1359   pattern used for QModelIndex and QAbstractItemModel.
1360  */
1361
1362 /*!
1363   \since 4.4
1364   \relates QHash
1365
1366   Computes a hash key from the QXmlNodeModelIndex \a index, and
1367   returns it. This function would be used by QHash if you wanted
1368   to build a hash table for instances of QXmlNodeModelIndex.
1369
1370   The hash is computed on QXmlNodeModelIndex::data(),
1371   QXmlNodeModelIndex::additionalData(), and
1372   QXmlNodeModelIndex::model(). This means the hash key can be used for
1373   node indexes from different node models.
1374  */
1375 uint qHash(const QXmlNodeModelIndex &index)
1376 {
1377     return uint(index.data() + index.additionalData() + quintptr(index.model()));
1378 }
1379
1380 /*!
1381   \enum QXmlNodeModelIndex::NodeKind
1382
1383   Identifies a kind of node.
1384
1385   \value Attribute Identifies an attribute node
1386   \value Text Identifies a text node
1387   \value Comment Identifies a comment node
1388   \value Document Identifies a document node
1389   \value Element Identifies an element node
1390   \value Namespace Identifies a namespace node
1391   \value ProcessingInstruction Identifies a processing instruction.
1392
1393   Note that the optional XML declaration at very beginning of the XML
1394   document is not a processing instruction
1395
1396   \sa QAbstractXmlNodeModel::kind()
1397 */
1398
1399 /*!
1400  \typedef QXmlNodeModelIndex::List
1401
1402  Typedef for QList<QXmlNodeModelIndex>.
1403  */
1404
1405 /*!
1406   Returns true if this node is the same as \a other. This operator
1407   does not compare values, children, or names of nodes. It compares
1408   node identities, i.e., whether two nodes are from the same document
1409   and are found at the exact same place.
1410  */
1411 bool QXmlNodeModelIndex::operator==(const QXmlNodeModelIndex &other) const
1412 {
1413     return !(m_storage != other.m_storage);
1414 }
1415
1416 /*!
1417   Returns true if \a other is the same node as this.
1418  */
1419 bool QXmlNodeModelIndex::operator!=(const QXmlNodeModelIndex &other) const
1420 {
1421     return !(operator==(other));
1422 }
1423
1424 /*!
1425  \fn QXmlNodeModelIndex::QXmlNodeModelIndex()
1426
1427  Default constructor. Creates an item that is \c null.
1428
1429  \sa isNull()
1430  */
1431
1432 /*!
1433  \fn QXmlNodeModelIndex::QXmlNodeModelIndex(const QXmlNodeModelIndex &other)
1434
1435  Standard copy constructor. Creates a QXmlNodeModelIndex instance that
1436  is a copy of \a other.
1437  */
1438
1439 /*!
1440  \fn bool QXmlNodeModelIndex::isNull() const
1441
1442  Returns true if this QXmlNodeModelIndex is a default constructed
1443  value, otherwise false.
1444
1445  A null QXmlNodeModelIndex doesn't represent any node and cannot
1446  be used in conjunction with QAbstractXmlNodeModel.
1447  */
1448
1449 /*!
1450  \fn const QAbstractXmlNodeModel *QXmlNodeModelIndex::model() const
1451
1452  Returns the QAbstractXmlNodeModel that this node index refers to.
1453  QXmlNodeModelIndex does not own QAbstractXmlNodeModel and does not
1454  keep track of its lifetime, so this pointer will dangle if the
1455  QAbstractXmlNodeModel is deallocated first.
1456
1457  There is no setter for the node model because instances of
1458  QXmlNodeModelIndex instances are only created with
1459  QAbstractXmlNodeModel::createIndex().
1460 */
1461
1462 /*!
1463  \fn qint64 QXmlNodeModelIndex::data() const
1464
1465  Returns the first data value. The node index holds two data values.
1466  additionalData() returns the second one.
1467
1468  \sa additionalData()
1469 */
1470
1471 /*!
1472  \fn void *QXmlNodeModelIndex::internalPointer() const
1473
1474  Returns the first data value as a void* pointer.
1475
1476  \sa additionalData()
1477 */
1478
1479 /*!
1480  \fn qint64 QXmlNodeModelIndex::additionalData() const
1481
1482  Returns the second data value. The node index holds two data values.
1483  data() returns the first one.
1484
1485  \sa data()
1486 */
1487
1488 /*!
1489  \fn void QXmlNodeModelIndex::reset()
1490  \internal
1491
1492  Resets this QXmlNodeModelIndex to be null. It is equivalent to
1493  writing:
1494
1495  \snippet doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlnodemodel.cpp 0
1496  */
1497
1498 /*!
1499  \fn QXmlName QXmlNodeModelIndex::name() const
1500  \internal
1501 */
1502
1503 /*!
1504  \typedef QXmlNodeModelIndex::Iterator
1505  \internal
1506
1507  Typedef for QAbstractXmlForwardIterator<QXmlNodeModelIndex>.
1508  */
1509 /*!
1510  \fn QXmlNodeModelIndex QXmlNodeModelIndex::root() const
1511  \internal
1512 */
1513
1514 /*!
1515  \fn QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QXmlNodeModelIndex> > QXmlNodeModelIndex::iterate(const Axis axis) const
1516  \internal
1517 */
1518
1519 /*!
1520  \fn QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QPatternist::Item> > QXmlNodeModelIndex::sequencedTypedValue() const
1521  \internal
1522 */
1523
1524 /*!
1525  \fn QUrl QXmlNodeModelIndex::documentUri() const
1526  \internal
1527 */
1528
1529 /*!
1530  \fn QUrl QXmlNodeModelIndex::baseUri() const
1531  \internal
1532 */
1533
1534 /*!
1535  \fn NodeKind QXmlNodeModelIndex::kind() const
1536  \internal
1537 */
1538
1539 /*!
1540  \fn bool QXmlNodeModelIndex::isDeepEqual(const QXmlNodeModelIndex &other) const
1541  \internal
1542 */
1543
1544 /*!
1545  \fn DocumentOrder QXmlNodeModelIndex::compareOrder(const QXmlNodeModelIndex &other) const
1546  \internal
1547 */
1548
1549 /*!
1550  \fn void QXmlNodeModelIndex::sendNamespaces(QAbstractXmlReceiver *const receiver) const
1551  \internal
1552 */
1553
1554 /*!
1555  \fn QVector<QXmlName> QXmlNodeModelIndex::namespaceBindings() const
1556  \internal
1557 */
1558
1559 /*!
1560  \fn QXmlNodeModelIndex QAbstractXmlNodeModel::elementById(const QXmlName &id) const
1561
1562  Returns the index of the element identified as \a id. XQuery's \c
1563  id() function calls this function.
1564
1565  The node index returned will be the element node whose value is of
1566  type \c ID and equals \a id, or it will be the element node that has
1567  an attribute whose typed value is of type \c ID and equals \a id. If
1568  there is no such element, a default constructed QXmlNodeModelIndex
1569  instance is returned. The implementor guarantees that if the returned
1570  node index is not null, it identifies an element.
1571
1572  It is not sufficient for an attribute or element to merely be called
1573  \c id. Its value type must also be \c ID. However, the reserved name
1574  \c xml:id is sufficient.
1575
1576  In \a id, the \c{namespace URI} and the \c{prefix} are undefined, and
1577  the \c{local name} is the ID that should be looked up.
1578
1579  \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}
1580  */
1581
1582 /*!
1583  \fn QVector<QXmlNodeModelIndex> QAbstractXmlNodeModel::nodesByIdref(const QXmlName &idref) const
1584
1585  Returns the elements and/or attributes that have an \c IDREF value
1586  equal to \a idref. XQuery's \c idref() function calls this function.
1587
1588  The implementor guarantees that the nodes identified by the returned
1589  indexes are elements or attributes.
1590
1591  It is not sufficient for an attribute or element to merely be called
1592  \c idref. It must also be of type \c IDREF. Elements must be typed as
1593  \c xs:IDREF or \c xs:IDREFS, or, in the case of attributes, as \c
1594  IDREF or \c IDREFS in the schema.
1595
1596  In \a idref, the \c{namespace URI} and the \c{prefix} are undefined,
1597  and the \c{local name} is the ID that should be looked up.
1598
1599  \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}
1600  */
1601
1602 /*!
1603  \fn QXmlName::NamespaceCode QXmlNodeModelIndex::namespaceForPrefix(const QXmlName::PrefixCode prefix) const
1604  \internal
1605 */
1606
1607 /*!
1608  \fn QString QXmlNodeModelIndex::stringValue() const
1609  \internal
1610 */
1611
1612 /*!
1613  \fn QPatternist::ItemTypePtr QXmlNodeModelIndex::type() const
1614  \internal
1615 */
1616
1617 /*!
1618  \fn bool QXmlNodeModelIndex::is(const QXmlNodeModelIndex &other) const
1619  \internal
1620 */
1621
1622 /*!
1623  \enum QAbstractXmlNodeModel::NodeCopySetting
1624  \internal
1625
1626  Controls how nodes are copied with copyNodeTo.
1627
1628  \value InheritNamespaces Copies the node with the \c copy-namespaces
1629         setting being \c inherit. If not set, \c no-inherit is assumed.
1630  \value PreserveNamespaces Copies the node with the \c copy-namespaces
1631         settings being \c preserve. If not set, \c no-preserve is assumed.
1632  */
1633
1634 /*!
1635  \typedef QAbstractXmlNodeModel::NodeCopySettings
1636  \internal
1637  */
1638
1639 /*!
1640  \internal
1641
1642  Copies node \a node to \a receiver, steered by \a copySettings.
1643
1644  The caller guarantees that \a node is not \c null, and that is
1645  belongs to this QAbstractXmlNodeModel instance.
1646
1647  The caller guarantees that \a receiver is not \c null.
1648 */
1649 void QAbstractXmlNodeModel::copyNodeTo(const QXmlNodeModelIndex &node,
1650                                        QAbstractXmlReceiver *const receiver,
1651                                        const NodeCopySettings &copySettings) const
1652 {
1653     Q_UNUSED(node);
1654     Q_UNUSED(receiver);
1655     Q_UNUSED(copySettings);
1656     Q_ASSERT_X(false, Q_FUNC_INFO,
1657                "This function is not expected to be called.");
1658 }
1659
1660 /*!
1661     Returns the source location for the object with the given \a index
1662     or a default constructed QSourceLocation in case no location
1663     information is available.
1664
1665     \since 4.6
1666 */
1667 QSourceLocation QAbstractXmlNodeModel::sourceLocation(const QXmlNodeModelIndex &index) const
1668 {
1669     // TODO: make this method virtual in Qt5 to allow source location support in custom models
1670     if (d_ptr)
1671         return d_ptr->sourceLocation(index);
1672     else
1673         return QSourceLocation();
1674 }
1675
1676 QT_END_NAMESPACE