1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtXmlPatterns module of the Qt Toolkit.
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.
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.
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.
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.
40 ****************************************************************************/
44 #include "qabstractxmlnodemodel_p.h"
45 #include "qabstractxmlreceiver.h"
46 #include "qcommonvalues_p.h"
47 #include "qemptyiterator_p.h"
48 #include "qitemmappingiterator_p.h"
50 #include "qnamespaceresolver_p.h"
51 #include "qsequencemappingiterator_p.h"
52 #include "qsingletoniterator_p.h"
54 #include "qabstractxmlnodemodel.h"
58 using namespace QPatternist;
60 typedef QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QXmlNodeModelIndex> > QXmlNodeModelIndexIteratorPointer;
64 * @short Contains the implementation of QAbstractXmlNodeModel.
67 bool QAbstractXmlNodeModel::isIgnorableInDeepEqual(const QXmlNodeModelIndex &n)
69 Q_ASSERT(!n.isNull());
70 const QXmlNodeModelIndex::NodeKind nk = n.kind();
71 return nk == QXmlNodeModelIndex::ProcessingInstruction ||
72 nk == QXmlNodeModelIndex::Comment;
77 \class QAbstractXmlNodeModel
78 \brief The QAbstractXmlNodeModel class is an abstract base class for modeling non-XML data to look like XML for QXmlQuery.
82 \inmodule QtXmlPatterns
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.
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.
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.
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}.
113 \snippet doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlnodemodel.cpp 1
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.
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
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.
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}.
159 The example demonstrates the standard pattern for using a subclass
160 of QAbstractXmlNodeModel in combination with QXmlQuery to perform
165 \li Instantiate QXmlQuery and give it the XQuery to be run;
167 \li Instantiate a subclass of QAbstractXmlNodeModel or
170 \li Retrieve a QXmlNodeModelIndex for the node in the model where
171 the QXmlQuery should start the query;
173 \li Use QXmlQuery::bindVariable() to bind the QXmlNodeModelIndex
174 to \c {$variable name};
176 \li Call one of the QXmlQuery evaluation functions to run the
181 \section1 Subclassing
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.
190 \section1 Thread Safety
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
198 See the example \l{File System Example} for a demonstration.
202 \enum QXmlNodeModelIndex::Constants
204 \value ForwardAxis All forward axes include this flag.
205 \value ReverseAxis All reverse axes include this flag.
209 \enum QXmlNodeModelIndex::DocumentOrder
211 Identifies the specific node comparison operator that should be
214 \value Precedes Signifies the \c \<\< operator. Test whether the
215 first operand precedes the second in the document.
217 \value Follows Signifies the \c \>\> operator. Test whether the
218 first operand follows the second in the document.
220 \value Is Signifies the \c is operator. Test whether two nodes have
221 the same node identity.
225 \enum QAbstractXmlNodeModel::SimpleAxis
227 Four axes that each contain one node only.
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
236 \enum QXmlNodeModelIndex::Axis
239 Identify the axes emanating from a node.
241 The axes AxisChild, AxisDescendant, AxisAttribute, AxisSelf,
242 AxisDescendantOrSelf, AxisFollowingSibling, and AxisFollowing are
245 The axes AxisParent, AxisAncestor, AxisPrecedingSibling,
246 AxisPreceding and AxisAncestorOrSelf are reverse axes.
248 \sa {http://www.w3.org/TR/xquery/#axes}{XQuery 1.0: An XML Query Language, 3.2.1.1 Axes}
250 \value AxisChild The \c child axis.
252 \value AxisDescendant The \c descendant axis.
254 \value AxisAttribute The \c attribute axis. Note: There
255 is a node kind named \c{Attribute}.
257 \value AxisSelf The \c self axis.
259 \value AxisDescendantOrSelf The \c descendant-or-self axis.
261 \value AxisFollowingSibling The \c following-sibling axis.
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.
268 \value AxisFollowing The \c following axis.
270 \value AxisParent The \c parent axis.
272 \value AxisAncestor The \c ancestor axis.
274 \value AxisPrecedingSibling The \c preceding-sibling axis.
276 \value AxisPreceding The \c preceding axis.
278 \value AxisAncestorOrSelf The \c ancestor-or-self axis.
281 using namespace QPatternist;
286 QAbstractXmlNodeModel::QAbstractXmlNodeModel() : d_ptr(0)
296 QAbstractXmlNodeModel::QAbstractXmlNodeModel(QAbstractXmlNodeModelPrivate *d) : d_ptr(d)
303 QAbstractXmlNodeModel::~QAbstractXmlNodeModel()
308 \typedef QAbstractXmlNodeModel::List
310 A \l{QList}{list} of \l{QExplicitlySharedDataPointer} {smart
311 pointers} to instances of QAbstractXmlNodeModel.
313 \sa QExplicitlySharedDataPointer
317 \typedef QAbstractXmlNodeModel::Ptr
319 A \l {QExplicitlySharedDataPointer} {smart pointer} to an
320 instance of QAbstractXmlNodeModel.
322 \sa QExplicitlySharedDataPointer
326 \fn QUrl QAbstractXmlNodeModel::baseUri(const QXmlNodeModelIndex &n) const
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
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
338 This function maps to the \c dm:base-uri accessor, which returns
339 a base URI according to the following:
343 \li For document nodes, the base URI and the document URI are the same.
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.
349 \li Namespace nodes have no base URI.
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.
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.
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}
364 \fn QUrl QAbstractXmlNodeModel::documentUri(const QXmlNodeModelIndex &n) const
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.
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.
376 The caller guarantees that \a n is not \c null and that it belongs
377 to this QAbstractXmlNodeModel.
379 This function maps to the \c dm:document-uri accessor, which
380 returns a document URI according to the following:
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.
388 \li For all other nodes, return a default constructed QUrl.
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()
401 virtual QSourceLocation sourceLocation(const QXmlNodeModelIndex &nodeIndex) const = 0;
403 Such that the data model can communicate back source locations.
407 \fn QXmlNodeModelIndex::NodeKind QAbstractXmlNodeModel::kind(const QXmlNodeModelIndex &ni) const
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.
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}
418 \fn QXmlNodeModelIndex::DocumentOrder QAbstractXmlNodeModel::compareOrder(const QXmlNodeModelIndex &ni1, const QXmlNodeModelIndex &ni2) const
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.
424 The caller guarantees that \a ni1 and \a ni2 are not \c null and
425 that both identify nodes in this node model.
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.
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}
436 \fn QXmlNodeModelIndex QAbstractXmlNodeModel::root(const QXmlNodeModelIndex &n) const
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.
442 If \a n identifies a node that is a direct child of the root,
443 parent() would return the same QXmlNodeModelIndex returned by
447 namespace QPatternist
452 inline MergeIterator()
457 QXmlNodeModelIndexIteratorPointer
458 mapToSequence(const QXmlNodeModelIndexIteratorPointer &it,
459 const DynamicContext::Ptr &) const
465 Q_DISABLE_COPY(MergeIterator)
468 static const MergeIterator mergeIterator;
471 * One might wonder, why not use makeVectorIterator() directly on a QVector
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.
481 class IteratorVector : public ListIterator<QXmlNodeModelIndexIteratorPointer, QVector<QXmlNodeModelIndexIteratorPointer> >
483 typedef QVector<QXmlNodeModelIndexIteratorPointer> ItVector;
485 typedef QAbstractXmlForwardIterator<QXmlNodeModelIndexIteratorPointer>::Ptr Ptr;
487 IteratorVector(const ItVector &in) : ListIterator<QXmlNodeModelIndexIteratorPointer, QVector<QXmlNodeModelIndexIteratorPointer> >(in)
491 virtual QAbstractXmlForwardIterator<QXmlNodeModelIndexIteratorPointer>::Ptr copy() const
495 for(int i = 0; i < m_list.count(); ++i)
496 result.append(m_list.at(i)->copy());
498 return Ptr(new IteratorVector(result));
505 This function is not a private member of QAbstractXmlNodeModel
506 because it would be messy to forward declare the required types.
508 static inline QXmlNodeModelIndexIteratorPointer mergeIterators(const QXmlNodeModelIndex &node,
509 const QXmlNodeModelIndexIteratorPointer &it2)
511 QVector<QXmlNodeModelIndexIteratorPointer> iterators;
512 iterators.append(makeSingletonIterator(node));
513 iterators.append(it2);
515 return makeSequenceMappingIterator<QXmlNodeModelIndex>(&mergeIterator,
516 IteratorVector::Ptr(new IteratorVector(iterators)),
517 DynamicContext::Ptr());
520 inline QAbstractXmlForwardIterator<QXmlNodeModelIndex>::Ptr
521 QAbstractXmlNodeModel::mapToSequence(const QXmlNodeModelIndex &ni,
522 const DynamicContext::Ptr &) const
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()));
532 \fn QVector<QXmlNodeModelIndex> QAbstractXmlNodeModel::attributes(const QXmlNodeModelIndex &element) const
534 Returns the attributes of \a element. The caller guarantees
535 that \a element is an element in this node model.
541 Performs navigation, starting from \a ni, by returning an
542 QAbstractXmlForwardIterator that returns nodes the \a axis emanating
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.
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.
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
565 QAbstractXmlNodeModel::Axis has a good overview of the axes and what
568 The caller guarantees that \a ni is not \c null and that it belongs
569 to this QAbstractXmlNodeModel instance.
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.
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)}
584 QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QXmlNodeModelIndex> >
585 QAbstractXmlNodeModel::iterate(const QXmlNodeModelIndex &ni,
586 QXmlNodeModelIndex::Axis axis) const
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(). */
595 case QXmlNodeModelIndex::AxisSelf:
596 return makeSingletonIterator(ni);
597 case QXmlNodeModelIndex::AxisParent:
599 if(kind(ni) == QXmlNodeModelIndex::Document)
600 return makeEmptyIterator<QXmlNodeModelIndex>();
602 return makeSingletonIterator(nextFromSimpleAxis(Parent, ni));
604 case QXmlNodeModelIndex::AxisNamespace:
605 return makeEmptyIterator<QXmlNodeModelIndex>();
606 case QXmlNodeModelIndex::AxisAncestor:
608 QList<QXmlNodeModelIndex> ancestors;
609 QXmlNodeModelIndex ancestor = nextFromSimpleAxis(Parent, ni);
611 while(!ancestor.isNull())
613 ancestors.append(ancestor);
614 ancestor = nextFromSimpleAxis(Parent, ancestor);
617 return makeListIterator(ancestors);
619 case QXmlNodeModelIndex::AxisAncestorOrSelf:
621 QList<QXmlNodeModelIndex> ancestors;
622 ancestors.append(ni);
623 QXmlNodeModelIndex ancestor = nextFromSimpleAxis(Parent, ni);
625 while(!ancestor.isNull())
627 ancestors.append(ancestor);
628 ancestor = nextFromSimpleAxis(Parent, ancestor);
631 return makeListIterator(ancestors);
633 case QXmlNodeModelIndex::AxisPrecedingSibling:
635 QList<QXmlNodeModelIndex> preceding;
636 QXmlNodeModelIndex sibling = nextFromSimpleAxis(PreviousSibling, ni);
638 while(!sibling.isNull())
640 preceding.append(sibling);
641 sibling = nextFromSimpleAxis(PreviousSibling, sibling);
644 return makeListIterator(preceding);
646 case QXmlNodeModelIndex::AxisFollowingSibling:
648 QList<QXmlNodeModelIndex> preceding;
649 QXmlNodeModelIndex sibling = nextFromSimpleAxis(NextSibling, ni);
651 while(!sibling.isNull())
653 preceding.append(sibling);
654 sibling = nextFromSimpleAxis(NextSibling, sibling);
657 return makeListIterator(preceding);
659 case QXmlNodeModelIndex::AxisChildOrTop:
661 if(nextFromSimpleAxis(Parent, ni).isNull())
665 case QXmlNodeModelIndex::Comment:
667 case QXmlNodeModelIndex::ProcessingInstruction:
669 case QXmlNodeModelIndex::Element:
671 case QXmlNodeModelIndex::Text:
672 return makeSingletonIterator(ni);
673 case QXmlNodeModelIndex::Attribute:
675 case QXmlNodeModelIndex::Document:
677 case QXmlNodeModelIndex::Namespace:
682 /* Else, fallthrough to AxisChild. */
684 case QXmlNodeModelIndex::AxisChild:
686 QList<QXmlNodeModelIndex> children;
687 QXmlNodeModelIndex child = nextFromSimpleAxis(FirstChild, ni);
689 while(!child.isNull())
691 children.append(child);
692 child = nextFromSimpleAxis(NextSibling, child);
695 return makeListIterator(children);
697 case QXmlNodeModelIndex::AxisDescendant:
699 return makeSequenceMappingIterator<QXmlNodeModelIndex>(this,
700 ni.iterate(QXmlNodeModelIndex::AxisChild),
701 DynamicContext::Ptr());
703 case QXmlNodeModelIndex::AxisAttributeOrTop:
705 if(kind(ni) == QXmlNodeModelIndex::Attribute && nextFromSimpleAxis(Parent, ni).isNull())
706 return makeSingletonIterator(ni);
708 /* Else, fallthrough to AxisAttribute. */
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:
716 case QXmlNodeModelIndex::AxisPreceding:
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;
723 QXmlNodeModelIndex current(ni);
724 while(!current.isNull())
726 QXmlNodeModelIndex candidate(nextFromSimpleAxis(axis == QXmlNodeModelIndex::AxisPreceding ? PreviousSibling : NextSibling, current));
727 if(candidate.isNull())
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);
736 descendantIterators.append(iterate(current, QXmlNodeModelIndex::AxisDescendantOrSelf)->toReversed());
740 return makeSequenceMappingIterator<QXmlNodeModelIndex>(&mergeIterator,
741 IteratorVector::Ptr(new IteratorVector(descendantIterators)),
742 DynamicContext::Ptr());
746 Q_ASSERT_X(false, Q_FUNC_INFO, "Unknown axis, internal error.");
747 return makeEmptyIterator<QXmlNodeModelIndex>();
751 \fn QXmlNodeModelIndex QAbstractXmlNodeModel::nextFromSimpleAxis(SimpleAxis axis, const QXmlNodeModelIndex &origin) const
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.
758 If no such node is available, a default constructed
759 QXmlNodeModelIndex is returned.
761 QSimpleXmlNodeModel eliminates the need to handle redundant corner
762 cases by guaranteeing that it will never ask for:
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.
770 A typical implementation performs a \c switch on the value of \a
774 QXmlNodeModelIndex MyTreeModel::nextFromSimpleAxis(SimpleAxis axis, const QXmlNodeModelIndex &origin) const
776 // Convert the QXmlNodeModelIndex to a value that is specific to what we represent.
777 const MyValue value = toMyValue(ni);
782 return toNodeIndex(value.parent());
784 case PreviousSibling:
794 \fn QXmlNodeModelIndex QAbstractXmlNodeModel::createIndex(qint64 data) const
796 Creates a node index with \a data as its internal data. \a data is
801 \fn QXmlNodeModelIndex QAbstractXmlNodeModel::createIndex(void *pointer, qint64 additionalData) const
803 Creates a node index with \a pointer and \a additionalData as
806 What \a pointer and \a additionalData is, is not constrained.
810 \fn QXmlNodeModelIndex QAbstractXmlNodeModel::createIndex(qint64 data, qint64 additionalData) const;
813 Creates a QXmlNodeModelIndex containing \a data and \a
818 \fn QXmlName QAbstractXmlNodeModel::name(const QXmlNodeModelIndex &ni) const
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.
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.
828 This function maps to the \c dm:node-name() accessor.
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
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}
839 \fn QVector<QXmlName> QAbstractXmlNodeModel::namespaceBindings(const QXmlNodeModelIndex &n) const
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.
844 This function corresponds to the \c dm:namespace-nodes accessor.
846 The returned vector of namespace declarations includes namespaces
847 of the ancestors of \a n.
849 The caller guarantees that \a n is an Element that belongs to this
850 QAbstractXmlNodeModel.
855 Sends the namespaces declared on \a n to \a receiver.
857 As a consequence, no namespaces are sent unless this node is an
858 element and has namespaces declared.
860 The caller guarantees that \a n is not \c null and that it belongs
861 to this QAbstractXmlNodeModel instance.
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.
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
871 void QAbstractXmlNodeModel::sendNamespaces(const QXmlNodeModelIndex &n,
872 QAbstractXmlReceiver *const receiver) const
875 const QVector<QXmlName> nss(namespaceBindings(n));
877 /* This is by far the most common case. */
881 const int len = nss.size();
882 for(int i = 0; i < len; ++i)
883 receiver->namespaceBinding(nss.at(i));
887 \fn QString QAbstractXmlNodeModel::stringValue(const QXmlNodeModelIndex &n) const
889 Returns the string value for node \a n.
891 The caller guarantees that \a n is not \c null and that it belong to
892 this QAbstractXmlNodeModel instance.
894 This function maps to the \c dm:string-value() accessor, which the
895 specification completely specifies. Here's a summary:
899 \li For processing instructions, the string value is the data
900 section(excluding any whitespace appearing between the name and the
903 \li For text nodes, the string value equals the text node.
905 \li For comments, the content of the comment
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.
911 \li For document nodes, the concatenation of all text nodes in the
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}
920 \fn QVariant QAbstractXmlNodeModel::typedValue(const QXmlNodeModelIndex &node) const
922 Returns the typed value for node \a node.
924 The typed value is an atomic value, which an element or attribute
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()).
934 If the return QVariant is a default constructed variant, it signals
935 that \a node has no typed value.
941 QPatternist::ItemIteratorPtr QAbstractXmlNodeModel::sequencedTypedValue(const QXmlNodeModelIndex &ni) const
943 const QVariant &candidate = typedValue(ni);
944 if(candidate.isNull())
945 return QPatternist::CommonValues::emptyIterator;
947 return makeSingletonIterator(AtomicValue::toXDM(candidate));
953 QPatternist::ItemTypePtr QAbstractXmlNodeModel::type(const QXmlNodeModelIndex &) const
955 Q_ASSERT_X(false, Q_FUNC_INFO,
956 "This function is internal and must not be called.");
957 return QPatternist::ItemTypePtr();
963 Returns the namespace URI on \a ni that corresponds to \a prefix.
965 If \a prefix is StandardPrefixes::empty, the namespace URI for the
966 default namespace is returned.
968 The default implementation use namespaceBindings(), in a straight
971 If no namespace exists for \a prefix, NamespaceResolver::NoBinding
974 The caller guarantees to only call this function for element nodes.
976 QXmlName::NamespaceCode QAbstractXmlNodeModel::namespaceForPrefix(const QXmlNodeModelIndex &ni,
977 const QXmlName::PrefixCode prefix) const
979 Q_ASSERT(kind(ni) == QXmlNodeModelIndex::Element);
981 const QVector<QXmlName> nbs(namespaceBindings(ni));
982 const int len = nbs.size();
984 for(int i = 0; i < len; ++i)
986 if(nbs.at(i).prefix() == prefix)
987 return nbs.at(i).namespaceURI();
990 return NamespaceResolver::NoBinding;
997 Determines whether \a ni1 is deep equal to \a ni2.
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().
1006 Returns true if \a ni1 is deep-equal to \a ni2, otherwise false
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}
1010 bool QAbstractXmlNodeModel::isDeepEqual(const QXmlNodeModelIndex &n1,
1011 const QXmlNodeModelIndex &n2) const
1013 Q_ASSERT(!n1.isNull());
1014 Q_ASSERT(!n2.isNull());
1016 const QXmlNodeModelIndex::NodeKind nk = n1.kind();
1021 if(n1.name() != n2.name())
1026 case QXmlNodeModelIndex::Element:
1028 QXmlNodeModelIndexIteratorPointer atts1(n1.iterate(QXmlNodeModelIndex::AxisAttribute));
1029 QXmlNodeModelIndex node(atts1->next());
1031 const QXmlNodeModelIndex::List atts2(n2.iterate(QXmlNodeModelIndex::AxisAttribute)->toList());
1032 const QXmlNodeModelIndex::List::const_iterator end(atts2.constEnd());
1034 while(!node.isNull())
1037 for(QXmlNodeModelIndex::List::const_iterator it = atts2.constBegin(); it != end; ++it)
1039 if(isDeepEqual(node, (*it)))
1046 node = atts1->next();
1049 /* Fallthrough, so we check the children. */
1051 case QXmlNodeModelIndex::Document:
1053 QXmlNodeModelIndexIteratorPointer itn1(n1.iterate(QXmlNodeModelIndex::AxisChild));
1054 QXmlNodeModelIndexIteratorPointer itn2(n2.iterate(QXmlNodeModelIndex::AxisChild));
1058 QXmlNodeModelIndex no1(itn1->next());
1059 QXmlNodeModelIndex no2(itn2->next());
1061 while(!no1.isNull() && isIgnorableInDeepEqual(no1))
1064 while(!no2.isNull() && isIgnorableInDeepEqual(no2))
1067 if(!no1.isNull() && !no2.isNull())
1069 if(!isDeepEqual(no1, no2))
1073 return no1.isNull() && no2.isNull();
1078 case QXmlNodeModelIndex::Attribute:
1080 case QXmlNodeModelIndex::ProcessingInstruction:
1082 case QXmlNodeModelIndex::Text:
1084 case QXmlNodeModelIndex::Comment:
1085 return n1.stringValue() == n2.stringValue();
1086 case QXmlNodeModelIndex::Namespace:
1088 Q_ASSERT_X(false, Q_FUNC_INFO, "Not implemented");
1100 \brief The QXmlItem class contains either an XML node or an atomic value.
1102 \inmodule QtXmlPatterns
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.
1108 \quotefile doc/src/snippets/patternist/items.xq
1110 The five items are: An element, an atomic value (binary data encoded
1111 in base64), a date, a float, and an attribute.
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().
1123 A default constructed QXmlItem instance is neither a node nor an
1124 atomic value. It is considered null, in which case isNull() returns
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.
1133 \typedef QXmlItem::Iterator
1134 A QAbstractXmlForwardIterator over QXmlItem.
1138 Constructs a null QXmlItem that is neither a node nor an atomic
1139 value. isNull() returns true for a default constructed instance.
1141 QXmlItem::QXmlItem()
1146 bool QXmlItem::internalIsAtomicValue() const
1148 return m_node.model == reinterpret_cast<QAbstractXmlNodeModel *>(~0);
1152 The copy constructor constructs a copy of \a other.
1154 QXmlItem::QXmlItem(const QXmlItem &other) : m_node(other.m_node)
1156 if(internalIsAtomicValue())
1157 m_atomicValue->ref.ref();
1161 Constructs an atomic value QXmlItem with \a atomicValue.
1165 QXmlItem::QXmlItem(const QVariant &atomicValue)
1168 if(atomicValue.isNull())
1170 /* Then we behave just like the default constructor. */
1175 We can't assign directly to m_atomicValue, because the
1176 temporary will self-destruct before we've ref'd it.
1178 const QPatternist::Item temp(QPatternist::AtomicValue::toXDM(atomicValue));
1182 temp.asAtomicValue()->ref.ref();
1183 m_node.model = reinterpret_cast<const QAbstractXmlNodeModel *>(~0);
1184 m_atomicValue = temp.asAtomicValue();
1193 Constructs a node QXmlItem that is a copy of \a node.
1197 QXmlItem::QXmlItem(const QXmlNodeModelIndex &node) : m_node(node.m_storage)
1205 QXmlItem::~QXmlItem()
1207 if(internalIsAtomicValue() && !m_atomicValue->ref.deref())
1208 delete m_atomicValue;
1211 bool QPatternist::NodeIndexStorage::operator!=(const NodeIndexStorage &other) const
1213 return data != other.data
1214 || additionalData != other.additionalData
1215 || model != other.model;
1219 Assigns \a other to \c this.
1221 QXmlItem &QXmlItem::operator=(const QXmlItem &other)
1223 if(m_node != other.m_node)
1225 if(internalIsAtomicValue() && !m_atomicValue->ref.deref())
1226 delete m_atomicValue;
1228 m_node = other.m_node;
1230 if(internalIsAtomicValue())
1231 m_atomicValue->ref.ref();
1238 Returns true if this item is a Node. Returns false if it
1239 is an atomic value or null.
1241 \sa isNull(), isAtomicValue()
1243 bool QXmlItem::isNode() const
1245 return QPatternist::Item::fromPublic(*this).isNode();
1249 Returns true if this item is an atomic value. Returns false
1250 if it is a node or null.
1252 \sa isNull(), isNode()
1254 bool QXmlItem::isAtomicValue() const
1256 return internalIsAtomicValue();
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.
1268 QVariant QXmlItem::toAtomicValue() const
1271 return QPatternist::AtomicValue::toQt(m_atomicValue);
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
1284 QXmlNodeModelIndex QXmlItem::toNodeModelIndex() const
1287 return reinterpret_cast<const QXmlNodeModelIndex &>(m_node);
1289 return QXmlNodeModelIndex();
1293 Returns true if this QXmlItem is neither a node nor an
1294 atomic value. Default constructed instances of QXmlItem
1297 bool QXmlItem::isNull() const
1299 return !m_node.model;
1303 \class QXmlNodeModelIndex
1304 \brief The QXmlNodeModelIndex class identifies a node in an XML node model subclassed from QAbstractXmlNodeModel.
1308 \inmodule QtXmlPatterns
1310 QXmlNodeModelIndex is an index into an \l{QAbstractXmlNodeModel}
1311 {XML node model}. It contains:
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().
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.
1329 \li Send the output of your XQuery to an \l{QAbstractXmlReceiver}
1332 \li Let your XQuery do all the work to produce the desired result.
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
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.
1358 A default constructed node index is said to be null, i.e., isNull()
1361 QXmlNodeModelIndex and QAbstractXmlNodeModel follow the same design
1362 pattern used for QModelIndex and QAbstractItemModel.
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.
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.
1378 uint qHash(const QXmlNodeModelIndex &index)
1380 return uint(index.data() + index.additionalData() + quintptr(index.model()));
1384 \enum QXmlNodeModelIndex::NodeKind
1386 Identifies a kind of node.
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.
1396 Note that the optional XML declaration at very beginning of the XML
1397 document is not a processing instruction
1399 \sa QAbstractXmlNodeModel::kind()
1403 \typedef QXmlNodeModelIndex::List
1405 Typedef for QList<QXmlNodeModelIndex>.
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.
1414 bool QXmlNodeModelIndex::operator==(const QXmlNodeModelIndex &other) const
1416 return !(m_storage != other.m_storage);
1420 Returns true if \a other is the same node as this.
1422 bool QXmlNodeModelIndex::operator!=(const QXmlNodeModelIndex &other) const
1424 return !(operator==(other));
1428 \fn QXmlNodeModelIndex::QXmlNodeModelIndex()
1430 Default constructor. Creates an item that is \c null.
1436 \fn QXmlNodeModelIndex::QXmlNodeModelIndex(const QXmlNodeModelIndex &other)
1438 Standard copy constructor. Creates a QXmlNodeModelIndex instance that
1439 is a copy of \a other.
1443 \fn bool QXmlNodeModelIndex::isNull() const
1445 Returns true if this QXmlNodeModelIndex is a default constructed
1446 value, otherwise false.
1448 A null QXmlNodeModelIndex doesn't represent any node and cannot
1449 be used in conjunction with QAbstractXmlNodeModel.
1453 \fn const QAbstractXmlNodeModel *QXmlNodeModelIndex::model() const
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.
1460 There is no setter for the node model because instances of
1461 QXmlNodeModelIndex instances are only created with
1462 QAbstractXmlNodeModel::createIndex().
1466 \fn qint64 QXmlNodeModelIndex::data() const
1468 Returns the first data value. The node index holds two data values.
1469 additionalData() returns the second one.
1471 \sa additionalData()
1475 \fn void *QXmlNodeModelIndex::internalPointer() const
1477 Returns the first data value as a void* pointer.
1479 \sa additionalData()
1483 \fn qint64 QXmlNodeModelIndex::additionalData() const
1485 Returns the second data value. The node index holds two data values.
1486 data() returns the first one.
1492 \fn void QXmlNodeModelIndex::reset()
1495 Resets this QXmlNodeModelIndex to be null. It is equivalent to
1498 \snippet doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlnodemodel.cpp 0
1502 \fn QXmlName QXmlNodeModelIndex::name() const
1507 \typedef QXmlNodeModelIndex::Iterator
1510 Typedef for QAbstractXmlForwardIterator<QXmlNodeModelIndex>.
1513 \fn QXmlNodeModelIndex QXmlNodeModelIndex::root() const
1518 \fn QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QXmlNodeModelIndex> > QXmlNodeModelIndex::iterate(const Axis axis) const
1523 \fn QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QPatternist::Item> > QXmlNodeModelIndex::sequencedTypedValue() const
1528 \fn QUrl QXmlNodeModelIndex::documentUri() const
1533 \fn QUrl QXmlNodeModelIndex::baseUri() const
1538 \fn NodeKind QXmlNodeModelIndex::kind() const
1543 \fn bool QXmlNodeModelIndex::isDeepEqual(const QXmlNodeModelIndex &other) const
1548 \fn DocumentOrder QXmlNodeModelIndex::compareOrder(const QXmlNodeModelIndex &other) const
1553 \fn void QXmlNodeModelIndex::sendNamespaces(QAbstractXmlReceiver *const receiver) const
1558 \fn QVector<QXmlName> QXmlNodeModelIndex::namespaceBindings() const
1563 \fn QXmlNodeModelIndex QAbstractXmlNodeModel::elementById(const QXmlName &id) const
1565 Returns the index of the element identified as \a id. XQuery's \c
1566 id() function calls this function.
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.
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.
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.
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}
1586 \fn QVector<QXmlNodeModelIndex> QAbstractXmlNodeModel::nodesByIdref(const QXmlName &idref) const
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.
1591 The implementor guarantees that the nodes identified by the returned
1592 indexes are elements or attributes.
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.
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.
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}
1606 \fn QXmlName::NamespaceCode QXmlNodeModelIndex::namespaceForPrefix(const QXmlName::PrefixCode prefix) const
1611 \fn QString QXmlNodeModelIndex::stringValue() const
1616 \fn QPatternist::ItemTypePtr QXmlNodeModelIndex::type() const
1621 \fn bool QXmlNodeModelIndex::is(const QXmlNodeModelIndex &other) const
1626 \enum QAbstractXmlNodeModel::NodeCopySetting
1629 Controls how nodes are copied with copyNodeTo.
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.
1638 \typedef QAbstractXmlNodeModel::NodeCopySettings
1645 Copies node \a node to \a receiver, steered by \a copySettings.
1647 The caller guarantees that \a node is not \c null, and that is
1648 belongs to this QAbstractXmlNodeModel instance.
1650 The caller guarantees that \a receiver is not \c null.
1652 void QAbstractXmlNodeModel::copyNodeTo(const QXmlNodeModelIndex &node,
1653 QAbstractXmlReceiver *const receiver,
1654 const NodeCopySettings ©Settings) const
1658 Q_UNUSED(copySettings);
1659 Q_ASSERT_X(false, Q_FUNC_INFO,
1660 "This function is not expected to be called.");
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.
1670 QSourceLocation QAbstractXmlNodeModel::sourceLocation(const QXmlNodeModelIndex &index) const
1672 // TODO: make this method virtual in Qt5 to allow source location support in custom models
1674 return d_ptr->sourceLocation(index);
1676 return QSourceLocation();