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