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.
83 The QAbstractXmlNodeModel specifies the interface that a node model
84 must implement for that node model be accessible to the query engine
85 for processing XQuery queries. A node model represents data as a
86 structure that can be queried as if the data were XML.
88 The node model represented by a subclass of QAbstractXmlNodeModel is
89 meant to be accessed by the QtXmlPatterns query engine. If the API
90 seems a little strange in a few places, it is because the member
91 functions are called by the query engine as it evaluates an
92 XQuery. They aren't meant to be used programatically.
96 QAbstractXmlNodeModel bridges the gap between the arbitrary structure
97 of the non-XML data to be queried and the well-defined structure of
98 XML data understood by QXmlQuery.
100 Consider a chemistry application that reads the file \c
101 chemistryData, which contains non-XML data that represents a
102 chemical structure composed of molecules and atoms. The application
103 will query this chemistry data with an XQuery it reads from file \c
104 queryFile. We write a custom subclass of QAbstractXmlNodeModel (\c
105 ChemistryNodeModel) that reads \c chemistryData and builds a data
106 structure, perhaps composed of objects of our own classes \c
107 molecule and \c atom. Clearly, this data structure is not XML. Our
108 custom subclass will know how to traverse this non-XML structure and
109 present it through the \l
110 {http://www.w3.org/TR/xpath-datamodel/}{XPath Data Model interface}.
112 \snippet doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlnodemodel.cpp 1
114 The application first creates an instance of QXmlQuery and calls \l
115 {QXmlQuery::setQuery()}{setQuery()} to read \c queryFile containing
116 the XQuery we want to run. Then it creates an instance of our custom
117 node model class, \c ChemistryNodeModel, which is a subclass of
118 QAbstractXmlNodeModel. Its constructor is called with the \l
119 {QXmlNamePool} {name pool} obtained from our QXmlQuery, and with the
120 \c chemistryFile containing the structure of molecules and atoms to
121 be queried. The \l {QXmlNamePool} {name pool} is required because
122 our custom node model has the member function \l
123 {QAbstractXmlNodeModel::name()} {name()}, which returns the \l
124 {QXmlName} {name} of any node in the model. The \l {QXmlQuery}
125 {query} and the custom node model must use the same name pool for
126 constructing these \l {QXmlName} {names}. The constructor would then
127 read \c chemistryFile and build the custom node model structure.
129 To connect the \c query to the custom node model, we must bind a
130 variable name used in the query to a node in the model. The variable
131 can then be used in the query as a starting node. First, an \l
132 {QXmlNodeModelIndex} {index} for the desired starting node is
133 retrieved by calling QAbstractXmlNodeModel::createIndex(). Then the
134 index is bound to a variable name, in this case \c queryRoot, by
135 passing the name and the index to QXmlQuery::bindVariable(). The
136 query can then use a variable reference \c $queryRoot to refer to
137 the starting node. Note that if the \l {QXmlQuery} {query} uses
138 multiple variable references, a call to QXmlQuery::bindVariable()
139 is required to bind each different variable name to a node in the
142 The query is executed when the application calls one of the
143 QXmlQuery evaluation functions. The application uses
144 QXmlQuery::evaluateTo(QAbstractXmlReceiver *), because it then uses
145 a \l {QXmlSerializer} {serializer} to out the query result as XML to
146 \c stdout. We could have used QXmlQuery::evaluateTo(QXmlResultItems
147 *) to get a list of result items, or
148 QXmlQuery::evaluateTo(QStringList *) if the query evaluated to a
149 sequence of \c {xs:string} values.
151 During query execution, the engine iterates over the node model
152 using nextFromSimpleAxis() to get the \l {QXmlNodeModelIndex}
153 {index} of the next node to be visited. The engine can get the name
154 of a node by calling name() with the node's \l {QXmlNodeModelIndex}
155 {index}. stringValue(), baseUri(), documentUri() and kind() are also
156 called as needed with a node \l {QXmlNodeModelIndex} {index}.
158 The example demonstrates the standard pattern for using a subclass
159 of QAbstractXmlNodeModel in combination with QXmlQuery to perform
164 \o Instantiate QXmlQuery and give it the XQuery to be run;
166 \o Instantiate a subclass of QAbstractXmlNodeModel or
169 \o Retrieve a QXmlNodeModelIndex for the node in the model where
170 the QXmlQuery should start the query;
172 \o Use QXmlQuery::bindVariable() to bind the QXmlNodeModelIndex
173 to \c {$variable name};
175 \o Call one of the QXmlQuery evaluation functions to run the
180 \section1 Subclassing
182 Because the \l {http://www.w3.org/TR/xpath-datamodel/}{XPath Data Model
183 interface} presented by QAbstractXmlNodeModel allows QXmlQuery to
184 operate on non-XML data as if it were XML, implementing subclasses
185 of QAbstractXmlNodeModel can involve a significant amount of
186 work. The QSimpleXmlNodeModel class is provided to simplify the
187 implementation for many common use cases.
189 \section1 Thread Safety
191 Because the node model can be accessed concurrently by threads in
192 the QtXmlPatterns module, subclasses of QAbstractXmlNodeModel must
193 be written to be \l{Reentrancy and Thread-Safety}{thread-safe}.
194 Classes that simplify implementing thread-safety include QReadLocker
197 See the example \l{File System Example} for a demonstration.
201 \enum QXmlNodeModelIndex::Constants
203 \value ForwardAxis All forward axes include this flag.
204 \value ReverseAxis All reverse axes include this flag.
208 \enum QXmlNodeModelIndex::DocumentOrder
210 Identifies the specific node comparison operator that should be
213 \value Precedes Signifies the \c \<\< operator. Test whether the
214 first operand precedes the second in the document.
216 \value Follows Signifies the \c \>\> operator. Test whether the
217 first operand follows the second in the document.
219 \value Is Signifies the \c is operator. Test whether two nodes have
220 the same node identity.
224 \enum QAbstractXmlNodeModel::SimpleAxis
226 Four axes that each contain one node only.
228 \value Parent The parent of the context node
229 \value FirstChild The first child of the context node
230 \value PreviousSibling The previous child of the context node
231 \value NextSibling The next child of the context node
235 \enum QXmlNodeModelIndex::Axis
238 Identify the axes emanating from a node.
240 The axes AxisChild, AxisDescendant, AxisAttribute, AxisSelf,
241 AxisDescendantOrSelf, AxisFollowingSibling, and AxisFollowing are
244 The axes AxisParent, AxisAncestor, AxisPrecedingSibling,
245 AxisPreceding and AxisAncestorOrSelf are reverse axes.
247 \sa {http://www.w3.org/TR/xquery/#axes}{XQuery 1.0: An XML Query Language, 3.2.1.1 Axes}
249 \value AxisChild The \c child axis.
251 \value AxisDescendant The \c descendant axis.
253 \value AxisAttribute The \c attribute axis. Note: There
254 is a node kind named \c{Attribute}.
256 \value AxisSelf The \c self axis.
258 \value AxisDescendantOrSelf The \c descendant-or-self axis.
260 \value AxisFollowingSibling The \c following-sibling axis.
262 \value AxisNamespace The \c namespace axis. Note: Does
263 not exist in XQuery; deprecated in
264 XPath 2.0 (optionally supported);
265 mandatory in XPath 1.0.
267 \value AxisFollowing The \c following axis.
269 \value AxisParent The \c parent axis.
271 \value AxisAncestor The \c ancestor axis.
273 \value AxisPrecedingSibling The \c preceding-sibling axis.
275 \value AxisPreceding The \c preceding axis.
277 \value AxisAncestorOrSelf The \c ancestor-or-self axis.
280 using namespace QPatternist;
285 QAbstractXmlNodeModel::QAbstractXmlNodeModel() : d_ptr(0)
295 QAbstractXmlNodeModel::QAbstractXmlNodeModel(QAbstractXmlNodeModelPrivate *d) : d_ptr(d)
302 QAbstractXmlNodeModel::~QAbstractXmlNodeModel()
307 \typedef QAbstractXmlNodeModel::List
309 A \l{QList}{list} of \l{QExplicitlySharedDataPointer} {smart
310 pointers} to instances of QAbstractXmlNodeModel.
312 \sa QExplicitlySharedDataPointer
316 \typedef QAbstractXmlNodeModel::Ptr
318 A \l {QExplicitlySharedDataPointer} {smart pointer} to an
319 instance of QAbstractXmlNodeModel.
321 \sa QExplicitlySharedDataPointer
325 \fn QUrl QAbstractXmlNodeModel::baseUri(const QXmlNodeModelIndex &n) const
327 Returns the base URI for the node whose index is \a n. The caller
328 guarantees that \a n is not \c null and that it belongs to a node
331 The base URI of a node can be extracted using the \c fn:base-uri()
332 function. The base URI is typically used for resolving relative URIs
333 that appear in the node or its children. It is conformant to just
334 return the document URI, although that might not properly reflect
337 This function maps to the \c dm:base-uri accessor, which returns
338 a base URI according to the following:
342 \o For document nodes, the base URI and the document URI are the same.
344 \o For elements, the base URI is the URI appearing in the element's
345 \c xml:base attribute, if present, or it is resolved to the
346 parent element's base URI.
348 \o Namespace nodes have no base URI.
350 \o The base URI for a processing instruction, comment, attribute,
351 or text node is the base URI of the node's parent element.
355 The implementation guarantees to return a valid QUrl, or a default
356 constructed QUrl. If a node has no base URI, as in the case where a
357 comment has no parent, a default constructed QUrl is returned.
359 \sa {http://www.w3.org/TR/xpath-datamodel/#dm-base-uri}{XQuery 1.0 and XPath 2.0 Data Model (XDM), 5.2 base-uri Accessor}
363 \fn QUrl QAbstractXmlNodeModel::documentUri(const QXmlNodeModelIndex &n) const
365 Returns the document URI of \a n. The document URI identifies the
366 resource which is the document. For example, the document could be a
367 regular file, e.g., \c{file:/}, or it could be the \c{http://} URL of
368 the location of a file. The document URI is used for resolving URIs
369 and to simply know where the document is.
371 If the node model maps to a URI in a natural way, return that URI.
372 Otherwise, return the company or product URI. The document URI can
373 be any URI as long as its valid and absolute.
375 The caller guarantees that \a n is not \c null and that it belongs
376 to this QAbstractXmlNodeModel.
378 This function maps to the \c dm:document-uri accessor, which
379 returns a document URI according to the following:
383 \o If \a n is a document node, return an absolute QUrl containing
384 the document URI, or a default constructed QUrl. The latter
385 signals that no document URI is available for the document node.
387 \o For all other nodes, return a default constructed QUrl.
391 \sa {http://www.w3.org/TR/xpath-datamodel/#dm-document-uri}{XQuery 1.0 and XPath 2.0 Data Model (XDM), 5.4 document-uri Accessor}
392 \sa QUrl::isValid(), QUrl::isRelative()
400 virtual QSourceLocation sourceLocation(const QXmlNodeModelIndex &nodeIndex) const = 0;
402 Such that the data model can communicate back source locations.
406 \fn QXmlNodeModelIndex::NodeKind QAbstractXmlNodeModel::kind(const QXmlNodeModelIndex &ni) const
408 Returns a value indicating the kind of node identified by \a ni.
409 The caller guarantees that \a ni is not null and that it identifies
410 a node in this node model. This function maps to the \c
411 dm:node-kind() accessor.
413 \sa {http://www.w3.org/TR/xpath-datamodel/#dm-node-kind}{XQuery 1.0 and XPath 2.0 Data Model (XDM), 5.10 node-kind Accessor}
417 \fn QXmlNodeModelIndex::DocumentOrder QAbstractXmlNodeModel::compareOrder(const QXmlNodeModelIndex &ni1, const QXmlNodeModelIndex &ni2) const
419 This function returns the relative document order for the
420 nodes indexed by \a ni1 and \a ni2. It is used for the \c Is
421 operator and for sorting nodes in document order.
423 The caller guarantees that \a ni1 and \a ni2 are not \c null and
424 that both identify nodes in this node model.
426 If \a ni1 is identical to \a ni2, QXmlNodeModelIndex::Is is returned.
427 If \a ni1 precedes \a ni2 in document order, QXmlNodeModelIndex::Precedes
428 is returned. If \a ni1 follows \a ni2 in document order,
429 QXmlNodeModelIndex::Follows is returned.
431 \sa {http://www.w3.org/TR/xpath-datamodel/#document-order}{XQuery 1.0 and XPath 2.0 Data Model (XDM), 2.4 Document Order}
435 \fn QXmlNodeModelIndex QAbstractXmlNodeModel::root(const QXmlNodeModelIndex &n) const
437 Returns the root node of the tree that contains the node whose index
438 is \a n. The caller guarantees that \a n is not \c null and that it
439 identifies a node in this node model.
441 If \a n identifies a node that is a direct child of the root,
442 parent() would return the same QXmlNodeModelIndex returned by
446 namespace QPatternist
451 inline MergeIterator()
456 QXmlNodeModelIndexIteratorPointer
457 mapToSequence(const QXmlNodeModelIndexIteratorPointer &it,
458 const DynamicContext::Ptr &) const
464 Q_DISABLE_COPY(MergeIterator)
467 static const MergeIterator mergeIterator;
470 * One might wonder, why not use makeVectorIterator() directly on a QVector
473 * A problem emerges QAbstractXmlForwardIterator::copy(). All "meta
474 * iterators" that contain other iterators and so forth, propagate the
475 * copy() call such that all involved iterators are copied. However, if we
476 * have a ListIterator of iterators it isn't aware of that it contains
477 * iterators. Hence, we have this class which is specialized(not in the
478 * template sense) on iterators, and hence copies them appropriately.
480 class IteratorVector : public ListIterator<QXmlNodeModelIndexIteratorPointer, QVector<QXmlNodeModelIndexIteratorPointer> >
482 typedef QVector<QXmlNodeModelIndexIteratorPointer> ItVector;
484 typedef QAbstractXmlForwardIterator<QXmlNodeModelIndexIteratorPointer>::Ptr Ptr;
486 IteratorVector(const ItVector &in) : ListIterator<QXmlNodeModelIndexIteratorPointer, QVector<QXmlNodeModelIndexIteratorPointer> >(in)
490 virtual QAbstractXmlForwardIterator<QXmlNodeModelIndexIteratorPointer>::Ptr copy() const
494 for(int i = 0; i < m_list.count(); ++i)
495 result.append(m_list.at(i)->copy());
497 return Ptr(new IteratorVector(result));
504 This function is not a private member of QAbstractXmlNodeModel
505 because it would be messy to forward declare the required types.
507 static inline QXmlNodeModelIndexIteratorPointer mergeIterators(const QXmlNodeModelIndex &node,
508 const QXmlNodeModelIndexIteratorPointer &it2)
510 QVector<QXmlNodeModelIndexIteratorPointer> iterators;
511 iterators.append(makeSingletonIterator(node));
512 iterators.append(it2);
514 return makeSequenceMappingIterator<QXmlNodeModelIndex>(&mergeIterator,
515 IteratorVector::Ptr(new IteratorVector(iterators)),
516 DynamicContext::Ptr());
519 inline QAbstractXmlForwardIterator<QXmlNodeModelIndex>::Ptr
520 QAbstractXmlNodeModel::mapToSequence(const QXmlNodeModelIndex &ni,
521 const DynamicContext::Ptr &) const
523 Q_ASSERT(!ni.isNull());
524 /* Since we pass in this here, mapToSequence is used recursively. */
525 return mergeIterators(ni, makeSequenceMappingIterator<QXmlNodeModelIndex>(this,
526 ni.iterate(QXmlNodeModelIndex::AxisChild),
527 DynamicContext::Ptr()));
531 \fn QVector<QXmlNodeModelIndex> QAbstractXmlNodeModel::attributes(const QXmlNodeModelIndex &element) const
533 Returns the attributes of \a element. The caller guarantees
534 that \a element is an element in this node model.
540 Performs navigation, starting from \a ni, by returning an
541 QAbstractXmlForwardIterator that returns nodes the \a axis emanating
544 The implementation returns the nodes on the \a axis, without
545 duplicates and in \a axis order. This means that if \a axis is a
546 reverse axis, which is the case for the \c parent, \c ancestor, \c
547 ancestor-or-self, \c preceding, and \c preceding-sibling, the nodes
548 are delivered in reverse document order. Otherwise the nodes are
549 delivered in document order.
551 The implementor guarantees that the nodes delivered for the axes are
552 consistent with the XPath Data Model. This just implies common
553 sense, e.g., The child axis for a comment node can't contain any
554 children; a document node can't be a child of an element, etc.
555 Attributes aren't considered children of an element, but are only
556 available on AxisAttribute.
558 The value past in \a axis is not guaranteed based on what is used in
559 a query. QtXmlPatterns may call this function arbitrarily with any
560 value for \a axis. This is because QtXmlPatterns may rewrite queries
561 to be more efficient, using axes in different ways from the original
564 QAbstractXmlNodeModel::Axis has a good overview of the axes and what
567 The caller guarantees that \a ni is not \c null and that it belongs
568 to this QAbstractXmlNodeModel instance.
570 Implementing iterate() can involve significant work, since it
571 requires different iterators for all the axes used. In the worst
572 case, it could require writing as many QAbstractXmlForwardIterator
573 subclasses as there are axes, but the number can often be reduced
574 with clever use of lists and template classes. It is better to use
575 or subclass QSimpleXmlNodeModel, which makes it easier to write the
576 node navigation code without loss of efficiency or flexibility.
578 \sa QSimpleXmlNodeModel
579 \sa QXmlNodeModelIndex::Axis
580 \sa {http://www.w3.org/TR/xquery/#axes}{XQuery 1.0: An XML Query Language, 3.2.1.1 Axes}
581 \sa {http://www.w3.org/TR/xpath-datamodel/}{W3CXQuery 1.0 and XPath 2.0 Data Model (XDM)}
583 QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QXmlNodeModelIndex> >
584 QAbstractXmlNodeModel::iterate(const QXmlNodeModelIndex &ni,
585 QXmlNodeModelIndex::Axis axis) const
587 /* Returns iterators that track state and calls nextFromSimpleAxis()
588 * iteratively. Typically, when sub-classing QSimpleXmlNodeModel,
589 * you don't reimplement this function, but instead implement
590 * nextFromSimpleAxis(). */
594 case QXmlNodeModelIndex::AxisSelf:
595 return makeSingletonIterator(ni);
596 case QXmlNodeModelIndex::AxisParent:
598 if(kind(ni) == QXmlNodeModelIndex::Document)
599 return makeEmptyIterator<QXmlNodeModelIndex>();
601 return makeSingletonIterator(nextFromSimpleAxis(Parent, ni));
603 case QXmlNodeModelIndex::AxisNamespace:
604 return makeEmptyIterator<QXmlNodeModelIndex>();
605 case QXmlNodeModelIndex::AxisAncestor:
607 QList<QXmlNodeModelIndex> ancestors;
608 QXmlNodeModelIndex ancestor = nextFromSimpleAxis(Parent, ni);
610 while(!ancestor.isNull())
612 ancestors.append(ancestor);
613 ancestor = nextFromSimpleAxis(Parent, ancestor);
616 return makeListIterator(ancestors);
618 case QXmlNodeModelIndex::AxisAncestorOrSelf:
620 QList<QXmlNodeModelIndex> ancestors;
621 ancestors.append(ni);
622 QXmlNodeModelIndex ancestor = nextFromSimpleAxis(Parent, ni);
624 while(!ancestor.isNull())
626 ancestors.append(ancestor);
627 ancestor = nextFromSimpleAxis(Parent, ancestor);
630 return makeListIterator(ancestors);
632 case QXmlNodeModelIndex::AxisPrecedingSibling:
634 QList<QXmlNodeModelIndex> preceding;
635 QXmlNodeModelIndex sibling = nextFromSimpleAxis(PreviousSibling, ni);
637 while(!sibling.isNull())
639 preceding.append(sibling);
640 sibling = nextFromSimpleAxis(PreviousSibling, sibling);
643 return makeListIterator(preceding);
645 case QXmlNodeModelIndex::AxisFollowingSibling:
647 QList<QXmlNodeModelIndex> preceding;
648 QXmlNodeModelIndex sibling = nextFromSimpleAxis(NextSibling, ni);
650 while(!sibling.isNull())
652 preceding.append(sibling);
653 sibling = nextFromSimpleAxis(NextSibling, sibling);
656 return makeListIterator(preceding);
658 case QXmlNodeModelIndex::AxisChildOrTop:
660 if(nextFromSimpleAxis(Parent, ni).isNull())
664 case QXmlNodeModelIndex::Comment:
666 case QXmlNodeModelIndex::ProcessingInstruction:
668 case QXmlNodeModelIndex::Element:
670 case QXmlNodeModelIndex::Text:
671 return makeSingletonIterator(ni);
672 case QXmlNodeModelIndex::Attribute:
674 case QXmlNodeModelIndex::Document:
676 case QXmlNodeModelIndex::Namespace:
681 /* Else, fallthrough to AxisChild. */
683 case QXmlNodeModelIndex::AxisChild:
685 QList<QXmlNodeModelIndex> children;
686 QXmlNodeModelIndex child = nextFromSimpleAxis(FirstChild, ni);
688 while(!child.isNull())
690 children.append(child);
691 child = nextFromSimpleAxis(NextSibling, child);
694 return makeListIterator(children);
696 case QXmlNodeModelIndex::AxisDescendant:
698 return makeSequenceMappingIterator<QXmlNodeModelIndex>(this,
699 ni.iterate(QXmlNodeModelIndex::AxisChild),
700 DynamicContext::Ptr());
702 case QXmlNodeModelIndex::AxisAttributeOrTop:
704 if(kind(ni) == QXmlNodeModelIndex::Attribute && nextFromSimpleAxis(Parent, ni).isNull())
705 return makeSingletonIterator(ni);
707 /* Else, fallthrough to AxisAttribute. */
709 case QXmlNodeModelIndex::AxisAttribute:
710 return makeVectorIterator(attributes(ni));
711 case QXmlNodeModelIndex::AxisDescendantOrSelf:
712 return mergeIterators(ni, iterate(ni, QXmlNodeModelIndex::AxisDescendant));
713 case QXmlNodeModelIndex::AxisFollowing:
715 case QXmlNodeModelIndex::AxisPreceding:
717 /* We walk up along the ancestors, and for each parent, we grab its preceding/following
718 * siblings, and evaluate the descendant axis. The descendant axes gets added
719 * to a list and we then merge those iterators. */
720 QVector<QXmlNodeModelIndexIteratorPointer> descendantIterators;
722 QXmlNodeModelIndex current(ni);
723 while(!current.isNull())
725 QXmlNodeModelIndex candidate(nextFromSimpleAxis(axis == QXmlNodeModelIndex::AxisPreceding ? PreviousSibling : NextSibling, current));
726 if(candidate.isNull())
728 /* current is an ancestor. We don't want it, so next iteration we
729 * will grab its preceding sibling. */
730 current = nextFromSimpleAxis(Parent, current);
735 descendantIterators.append(iterate(current, QXmlNodeModelIndex::AxisDescendantOrSelf)->toReversed());
739 return makeSequenceMappingIterator<QXmlNodeModelIndex>(&mergeIterator,
740 IteratorVector::Ptr(new IteratorVector(descendantIterators)),
741 DynamicContext::Ptr());
745 Q_ASSERT_X(false, Q_FUNC_INFO, "Unknown axis, internal error.");
746 return makeEmptyIterator<QXmlNodeModelIndex>();
750 \fn QXmlNodeModelIndex QAbstractXmlNodeModel::nextFromSimpleAxis(SimpleAxis axis, const QXmlNodeModelIndex &origin) const
752 When QtXmlPatterns evaluate path expressions, it emulate them through a
753 combination of calls with QSimpleXmlNodeModel::SimpleAxis values. Therefore,
754 the implementation of this function must return the node, if any, that
755 appears on the \a axis emanating from the \a origin.
757 If no such node is available, a default constructed
758 QXmlNodeModelIndex is returned.
760 QSimpleXmlNodeModel eliminates the need to handle redundant corner
761 cases by guaranteeing that it will never ask for:
764 \o Children or siblings for attributes.
765 \o Children for comments, processing instructions, and text nodes.
766 \o Siblings or parents for document nodes.
769 A typical implementation performs a \c switch on the value of \a
773 QXmlNodeModelIndex MyTreeModel::nextFromSimpleAxis(SimpleAxis axis, const QXmlNodeModelIndex &origin) const
775 // Convert the QXmlNodeModelIndex to a value that is specific to what we represent.
776 const MyValue value = toMyValue(ni);
781 return toNodeIndex(value.parent());
783 case PreviousSibling:
793 \fn QXmlNodeModelIndex QAbstractXmlNodeModel::createIndex(qint64 data) const
795 Creates a node index with \a data as its internal data. \a data is
800 \fn QXmlNodeModelIndex QAbstractXmlNodeModel::createIndex(void *pointer, qint64 additionalData) const
802 Creates a node index with \a pointer and \a additionalData as
805 What \a pointer and \a additionalData is, is not constrained.
809 \fn QXmlNodeModelIndex QAbstractXmlNodeModel::createIndex(qint64 data, qint64 additionalData) const;
812 Creates a QXmlNodeModelIndex containing \a data and \a
817 \fn QXmlName QAbstractXmlNodeModel::name(const QXmlNodeModelIndex &ni) const
819 Returns the name of \a ni. The caller guarantees that \a ni is not
820 \c null and that it belongs to this QAbstractXmlNodeModel.
822 If a node does not have a name, e.g., comment nodes, a null QXmlName
823 is returned. QXmlNames must be created with the instance of
824 QXmlQuery that is being used for evaluating queries using this
825 QAbstractXmlNodeModel.
827 This function maps to the \c dm:node-name() accessor.
829 If \a ni is a processing instruction, a QXmlName is returned with
830 the local name as the target name and the namespace URI and prefix
833 \sa {http://www.w3.org/TR/xpath-datamodel/#dm-node-name}{XQuery 1.0 and XPath 2.0 Data Model (XDM), 5.11 node-name Accessor}
838 \fn QVector<QXmlName> QAbstractXmlNodeModel::namespaceBindings(const QXmlNodeModelIndex &n) const
840 Returns the in-scope namespaces of \a n. The caller guarantees that
841 \a n is not \c null and that it belongs to this QAbstractXmlNodeModel.
843 This function corresponds to the \c dm:namespace-nodes accessor.
845 The returned vector of namespace declarations includes namespaces
846 of the ancestors of \a n.
848 The caller guarantees that \a n is an Element that belongs to this
849 QAbstractXmlNodeModel.
854 Sends the namespaces declared on \a n to \a receiver.
856 As a consequence, no namespaces are sent unless this node is an
857 element and has namespaces declared.
859 The caller guarantees that \a n is not \c null and that it belongs
860 to this QAbstractXmlNodeModel instance.
862 Note that it is not the namespaces that are in scope on \a n, but
863 only the namespaces that are specifically declared on \a n.
865 \a receiver is the receiver that this node is supposed to send its
866 namespaces to. This is guaranteed by the caller to be a valid
867 pointer. \a n is the index of the node whose namespaces are to
870 void QAbstractXmlNodeModel::sendNamespaces(const QXmlNodeModelIndex &n,
871 QAbstractXmlReceiver *const receiver) const
874 const QVector<QXmlName> nss(namespaceBindings(n));
876 /* This is by far the most common case. */
880 const int len = nss.size();
881 for(int i = 0; i < len; ++i)
882 receiver->namespaceBinding(nss.at(i));
886 \fn QString QAbstractXmlNodeModel::stringValue(const QXmlNodeModelIndex &n) const
888 Returns the string value for node \a n.
890 The caller guarantees that \a n is not \c null and that it belong to
891 this QAbstractXmlNodeModel instance.
893 This function maps to the \c dm:string-value() accessor, which the
894 specification completely specifies. Here's a summary:
898 \o For processing instructions, the string value is the data
899 section(excluding any whitespace appearing between the name and the
902 \o For text nodes, the string value equals the text node.
904 \o For comments, the content of the comment
906 \o For elements, the concatenation of all text nodes that are
907 descendants. Note, this is not only the children, but the
908 childrens' childrens' text nodes, and so forth.
910 \o For document nodes, the concatenation of all text nodes in the
915 \sa {http://www.w3.org/TR/xpath-datamodel/#dm-string-value}{XQuery 1.0 and XPath 2.0 Data Model (XDM), 5.13 string-value Accessor}
919 \fn QVariant QAbstractXmlNodeModel::typedValue(const QXmlNodeModelIndex &node) const
921 Returns the typed value for node \a node.
923 The typed value is an atomic value, which an element or attribute
926 The caller guarantees that \a node is either an element or an
927 attribute. The implementor guarantees that the returned QVariant has
928 a value which is supported in XQuery. It cannot be an arbitrary
929 QVariant value. The implementor also guarantees that stringValue()
930 returns a lexical representation of typedValue()(this is guaranteed
931 by QSimpleXmlNodeModel::stringValue()).
933 If the return QVariant is a default constructed variant, it signals
934 that \a node has no typed value.
940 QPatternist::ItemIteratorPtr QAbstractXmlNodeModel::sequencedTypedValue(const QXmlNodeModelIndex &ni) const
942 const QVariant &candidate = typedValue(ni);
943 if(candidate.isNull())
944 return QPatternist::CommonValues::emptyIterator;
946 return makeSingletonIterator(AtomicValue::toXDM(candidate));
952 QPatternist::ItemTypePtr QAbstractXmlNodeModel::type(const QXmlNodeModelIndex &) const
954 Q_ASSERT_X(false, Q_FUNC_INFO,
955 "This function is internal and must not be called.");
956 return QPatternist::ItemTypePtr();
962 Returns the namespace URI on \a ni that corresponds to \a prefix.
964 If \a prefix is StandardPrefixes::empty, the namespace URI for the
965 default namespace is returned.
967 The default implementation use namespaceBindings(), in a straight
970 If no namespace exists for \a prefix, NamespaceResolver::NoBinding
973 The caller guarantees to only call this function for element nodes.
975 QXmlName::NamespaceCode QAbstractXmlNodeModel::namespaceForPrefix(const QXmlNodeModelIndex &ni,
976 const QXmlName::PrefixCode prefix) const
978 Q_ASSERT(kind(ni) == QXmlNodeModelIndex::Element);
980 const QVector<QXmlName> nbs(namespaceBindings(ni));
981 const int len = nbs.size();
983 for(int i = 0; i < len; ++i)
985 if(nbs.at(i).prefix() == prefix)
986 return nbs.at(i).namespaceURI();
989 return NamespaceResolver::NoBinding;
996 Determines whether \a ni1 is deep equal to \a ni2.
998 isDeepEqual() is defined as evaluating the expression \c
999 fn:deep-equal($n1, $n2) where \c $n1 is \a ni1 and \c $n1 is \a
1000 ni2. This function is associative, meaning the same value is
1001 returned regardless of if isDeepEqual() is invoked with \a ni1 as
1002 first argument or second. It is guaranteed that \a ni1 and \a ni2
1003 are nodes, as opposed to the definition of \c fn:deep-equal().
1005 Returns true if \a ni1 is deep-equal to \a ni2, otherwise false
1007 \sa {"http://www.w3.org/TR/xpath-functions/#func-deep-equal"}{XQuery 1.0 and XPath 2.0 Functions and Operators, 15.3.1 fn:deep-equal}
1009 bool QAbstractXmlNodeModel::isDeepEqual(const QXmlNodeModelIndex &n1,
1010 const QXmlNodeModelIndex &n2) const
1012 Q_ASSERT(!n1.isNull());
1013 Q_ASSERT(!n2.isNull());
1015 const QXmlNodeModelIndex::NodeKind nk = n1.kind();
1020 if(n1.name() != n2.name())
1025 case QXmlNodeModelIndex::Element:
1027 QXmlNodeModelIndexIteratorPointer atts1(n1.iterate(QXmlNodeModelIndex::AxisAttribute));
1028 QXmlNodeModelIndex node(atts1->next());
1030 const QXmlNodeModelIndex::List atts2(n2.iterate(QXmlNodeModelIndex::AxisAttribute)->toList());
1031 const QXmlNodeModelIndex::List::const_iterator end(atts2.constEnd());
1033 while(!node.isNull())
1036 for(QXmlNodeModelIndex::List::const_iterator it = atts2.constBegin(); it != end; ++it)
1038 if(isDeepEqual(node, (*it)))
1045 node = atts1->next();
1048 /* Fallthrough, so we check the children. */
1050 case QXmlNodeModelIndex::Document:
1052 QXmlNodeModelIndexIteratorPointer itn1(n1.iterate(QXmlNodeModelIndex::AxisChild));
1053 QXmlNodeModelIndexIteratorPointer itn2(n2.iterate(QXmlNodeModelIndex::AxisChild));
1057 QXmlNodeModelIndex no1(itn1->next());
1058 QXmlNodeModelIndex no2(itn2->next());
1060 while(!no1.isNull() && isIgnorableInDeepEqual(no1))
1063 while(!no2.isNull() && isIgnorableInDeepEqual(no2))
1066 if(!no1.isNull() && !no2.isNull())
1068 if(!isDeepEqual(no1, no2))
1072 return no1.isNull() && no2.isNull();
1077 case QXmlNodeModelIndex::Attribute:
1079 case QXmlNodeModelIndex::ProcessingInstruction:
1081 case QXmlNodeModelIndex::Text:
1083 case QXmlNodeModelIndex::Comment:
1084 return n1.stringValue() == n2.stringValue();
1085 case QXmlNodeModelIndex::Namespace:
1087 Q_ASSERT_X(false, Q_FUNC_INFO, "Not implemented");
1099 \brief The QXmlItem class contains either an XML node or an atomic value.
1102 In XQuery, all expressions evaluate to a sequence of items, where
1103 each item is either an XML node or an atomic value. The query in the
1104 following snippet evaluates to sequence of five items.
1106 \quotefile doc/src/snippets/patternist/items.xq
1108 The five items are: An element, an atomic value (binary data encoded
1109 in base64), a date, a float, and an attribute.
1111 QXmlItem is the class that represents these XQuery items in the
1112 QtXmlPatterns API. A non-null instance of QXmlItem is either a node
1113 or an atomic value. Calling isNode() or isAtomicValue() tells you
1114 which it is. Atomic values are represented elsewhere in the Qt API
1115 as instances of QVariant, and an instance of QXmlItem that
1116 represents an atomic value can be converted to a QVariant by calling
1117 toAtomicValue(). A QXmlItem that wraps a node is represented
1118 elsewhere as an instance of QXmlNodeModelIndex. A node QXmlItem can
1119 be converted to a QXmlNodeModelIndex by calling toNodeModelIndex().
1121 A default constructed QXmlItem instance is neither a node nor an
1122 atomic value. It is considered null, in which case isNull() returns
1125 An instance of QXmlItem will be left dangling if the
1126 \l{QAbstractXmlNodeModel} {XML node model} it
1127 refers to is deleted, if it is a QXmlNodeModelIndex.
1131 \typedef QXmlItem::Iterator
1132 A QAbstractXmlForwardIterator over QXmlItem.
1136 Constructs a null QXmlItem that is neither a node nor an atomic
1137 value. isNull() returns true for a default constructed instance.
1139 QXmlItem::QXmlItem()
1144 bool QXmlItem::internalIsAtomicValue() const
1146 return m_node.model == reinterpret_cast<QAbstractXmlNodeModel *>(~0);
1150 The copy constructor constructs a copy of \a other.
1152 QXmlItem::QXmlItem(const QXmlItem &other) : m_node(other.m_node)
1154 if(internalIsAtomicValue())
1155 m_atomicValue->ref.ref();
1159 Constructs an atomic value QXmlItem with \a atomicValue.
1163 QXmlItem::QXmlItem(const QVariant &atomicValue)
1166 if(atomicValue.isNull())
1168 /* Then we behave just like the default constructor. */
1173 We can't assign directly to m_atomicValue, because the
1174 temporary will self-destruct before we've ref'd it.
1176 const QPatternist::Item temp(QPatternist::AtomicValue::toXDM(atomicValue));
1180 temp.asAtomicValue()->ref.ref();
1181 m_node.model = reinterpret_cast<const QAbstractXmlNodeModel *>(~0);
1182 m_atomicValue = temp.asAtomicValue();
1187 Constructs a node QXmlItem that is a copy of \a node.
1191 QXmlItem::QXmlItem(const QXmlNodeModelIndex &node) : m_node(node.m_storage)
1199 QXmlItem::~QXmlItem()
1201 if(internalIsAtomicValue() && !m_atomicValue->ref.deref())
1202 delete m_atomicValue;
1205 bool QPatternist::NodeIndexStorage::operator!=(const NodeIndexStorage &other) const
1207 return data != other.data
1208 || additionalData != other.additionalData
1209 || model != other.model;
1213 Assigns \a other to \c this.
1215 QXmlItem &QXmlItem::operator=(const QXmlItem &other)
1217 if(m_node != other.m_node)
1219 if(internalIsAtomicValue() && !m_atomicValue->ref.deref())
1220 delete m_atomicValue;
1222 m_node = other.m_node;
1224 if(internalIsAtomicValue())
1225 m_atomicValue->ref.ref();
1232 Returns true if this item is a Node. Returns false if it
1233 is an atomic value or null.
1235 \sa isNull(), isAtomicValue()
1237 bool QXmlItem::isNode() const
1239 return QPatternist::Item::fromPublic(*this).isNode();
1243 Returns true if this item is an atomic value. Returns false
1244 if it is a node or null.
1246 \sa isNull(), isNode()
1248 bool QXmlItem::isAtomicValue() const
1250 return internalIsAtomicValue();
1254 If this QXmlItem represents an atomic value, it is converted
1255 to an appropriate QVariant and returned. If this QXmlItem is
1256 not an atomic value, the return value is a default constructed
1257 QVariant. You can call isAtomicValue() to test whether the
1258 item is an atomic value.
1262 QVariant QXmlItem::toAtomicValue() const
1265 return QPatternist::AtomicValue::toQt(m_atomicValue);
1271 If this QXmlItem represents a node, it returns the item as a
1272 QXmlNodeModelIndex. If this QXmlItem is not a node, the return
1273 value is undefined. You can call isNode() to test whether the
1278 QXmlNodeModelIndex QXmlItem::toNodeModelIndex() const
1281 return reinterpret_cast<const QXmlNodeModelIndex &>(m_node);
1283 return QXmlNodeModelIndex();
1287 Returns true if this QXmlItem is neither a node nor an
1288 atomic value. Default constructed instances of QXmlItem
1291 bool QXmlItem::isNull() const
1293 return !m_node.model;
1297 \class QXmlNodeModelIndex
1298 \brief The QXmlNodeModelIndex class identifies a node in an XML node model subclassed from QAbstractXmlNodeModel.
1303 QXmlNodeModelIndex is an index into an \l{QAbstractXmlNodeModel}
1304 {XML node model}. It contains:
1307 \o A pointer to an \l{QAbstractXmlNodeModel} {XML node model},
1308 which is returned by model(), and
1309 \o Some data, which is returned by data(), internalPointer(),
1310 and additionalData().
1313 Because QXmlNodeModelIndex is intentionally a simple class, it
1314 doesn't have member functions for accessing the properties of
1315 nodes. For example, it doesn't have functions for getting a
1316 node's name or its list of attributes or child nodes. If you find
1317 that you need to retrieve this kind of information from your
1318 query results, there are two ways to proceed.
1322 \o Send the output of your XQuery to an \l{QAbstractXmlReceiver}
1325 \o Let your XQuery do all the work to produce the desired result.
1329 The second case is explained by example. Suppose you want to
1330 populate a list widget with the values of certain attributes from a
1331 set of result elements. You could write an XQuery to return the set
1332 of elements, and then you would write the code to iterate over the
1333 result elements, get their attributes, and extract the desired
1334 string values. But the simpler way is to just augment your XQuery to
1335 finding the desired attribute values. Then all you have to do is
1336 evaluate the XQuery using the version of QXmlQuery::evaluateTo()
1337 that populates a QStringList, which you can send directly to your
1340 QXmlNodeModelIndex doesn't impose any restrictions on the \c data
1341 value an QXmlNodeModelIndex should contain. The meaning of the data
1342 left to the associated \l {QAbstractXmlNodeModel} {node model}.
1343 Because QXmlNodeModelIndex depends on a particular subclass of
1344 QAbstractXmlNodeModel for its existence, the only way you can create
1345 an instance of QXmlNodeModelIndex is by asking the node model to
1346 create one for you with QAbstractXmlNodeModel::createIndex(). Since
1347 that function is protected, it is usually a good idea to write a
1348 public function that creates a QXmlNodeModelIndex from arguments that
1349 are appropriate for your particular node model.
1351 A default constructed node index is said to be null, i.e., isNull()
1354 QXmlNodeModelIndex and QAbstractXmlNodeModel follow the same design
1355 pattern used for QModelIndex and QAbstractItemModel.
1362 Computes a hash key from the QXmlNodeModelIndex \a index, and
1363 returns it. This function would be used by QHash if you wanted
1364 to build a hash table for instances of QXmlNodeModelIndex.
1366 The hash is computed on QXmlNodeModelIndex::data(),
1367 QXmlNodeModelIndex::additionalData(), and
1368 QXmlNodeModelIndex::model(). This means the hash key can be used for
1369 node indexes from different node models.
1371 uint qHash(const QXmlNodeModelIndex &index)
1373 return uint(index.data() + index.additionalData() + quintptr(index.model()));
1377 \enum QXmlNodeModelIndex::NodeKind
1379 Identifies a kind of node.
1381 \value Attribute Identifies an attribute node
1382 \value Text Identifies a text node
1383 \value Comment Identifies a comment node
1384 \value Document Identifies a document node
1385 \value Element Identifies an element node
1386 \value Namespace Identifies a namespace node
1387 \value ProcessingInstruction Identifies a processing instruction.
1389 Note that the optional XML declaration at very beginning of the XML
1390 document is not a processing instruction
1392 \sa QAbstractXmlNodeModel::kind()
1396 \typedef QXmlNodeModelIndex::List
1398 Typedef for QList<QXmlNodeModelIndex>.
1402 Returns true if this node is the same as \a other. This operator
1403 does not compare values, children, or names of nodes. It compares
1404 node identities, i.e., whether two nodes are from the same document
1405 and are found at the exact same place.
1407 bool QXmlNodeModelIndex::operator==(const QXmlNodeModelIndex &other) const
1409 return !(m_storage != other.m_storage);
1413 Returns true if \a other is the same node as this.
1415 bool QXmlNodeModelIndex::operator!=(const QXmlNodeModelIndex &other) const
1417 return !(operator==(other));
1421 \fn QXmlNodeModelIndex::QXmlNodeModelIndex()
1423 Default constructor. Creates an item that is \c null.
1429 \fn QXmlNodeModelIndex::QXmlNodeModelIndex(const QXmlNodeModelIndex &other)
1431 Standard copy constructor. Creates a QXmlNodeModelIndex instance that
1432 is a copy of \a other.
1436 \fn bool QXmlNodeModelIndex::isNull() const
1438 Returns true if this QXmlNodeModelIndex is a default constructed
1439 value, otherwise false.
1441 A null QXmlNodeModelIndex doesn't represent any node and cannot
1442 be used in conjunction with QAbstractXmlNodeModel.
1446 \fn const QAbstractXmlNodeModel *QXmlNodeModelIndex::model() const
1448 Returns the QAbstractXmlNodeModel that this node index refers to.
1449 QXmlNodeModelIndex does not own QAbstractXmlNodeModel and does not
1450 keep track of its lifetime, so this pointer will dangle if the
1451 QAbstractXmlNodeModel is deallocated first.
1453 There is no setter for the node model because instances of
1454 QXmlNodeModelIndex instances are only created with
1455 QAbstractXmlNodeModel::createIndex().
1459 \fn qint64 QXmlNodeModelIndex::data() const
1461 Returns the first data value. The node index holds two data values.
1462 additionalData() returns the second one.
1464 \sa additionalData()
1468 \fn void *QXmlNodeModelIndex::internalPointer() const
1470 Returns the first data value as a void* pointer.
1472 \sa additionalData()
1476 \fn qint64 QXmlNodeModelIndex::additionalData() const
1478 Returns the second data value. The node index holds two data values.
1479 data() returns the first one.
1485 \fn void QXmlNodeModelIndex::reset()
1488 Resets this QXmlNodeModelIndex to be null. It is equivalent to
1491 \snippet doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlnodemodel.cpp 0
1495 \fn QXmlName QXmlNodeModelIndex::name() const
1500 \typedef QXmlNodeModelIndex::Iterator
1503 Typedef for QAbstractXmlForwardIterator<QXmlNodeModelIndex>.
1506 \fn QXmlNodeModelIndex QXmlNodeModelIndex::root() const
1511 \fn QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QXmlNodeModelIndex> > QXmlNodeModelIndex::iterate(const Axis axis) const
1516 \fn QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QPatternist::Item> > QXmlNodeModelIndex::sequencedTypedValue() const
1521 \fn QUrl QXmlNodeModelIndex::documentUri() const
1526 \fn QUrl QXmlNodeModelIndex::baseUri() const
1531 \fn NodeKind QXmlNodeModelIndex::kind() const
1536 \fn bool QXmlNodeModelIndex::isDeepEqual(const QXmlNodeModelIndex &other) const
1541 \fn DocumentOrder QXmlNodeModelIndex::compareOrder(const QXmlNodeModelIndex &other) const
1546 \fn void QXmlNodeModelIndex::sendNamespaces(QAbstractXmlReceiver *const receiver) const
1551 \fn QVector<QXmlName> QXmlNodeModelIndex::namespaceBindings() const
1556 \fn QXmlNodeModelIndex QAbstractXmlNodeModel::elementById(const QXmlName &id) const
1558 Returns the index of the element identified as \a id. XQuery's \c
1559 id() function calls this function.
1561 The node index returned will be the element node whose value is of
1562 type \c ID and equals \a id, or it will be the element node that has
1563 an attribute whose typed value is of type \c ID and equals \a id. If
1564 there is no such element, a default constructed QXmlNodeModelIndex
1565 instance is returned. The implementor guarantees that if the returned
1566 node index is not null, it identifies an element.
1568 It is not sufficient for an attribute or element to merely be called
1569 \c id. Its value type must also be \c ID. However, the reserved name
1570 \c xml:id is sufficient.
1572 In \a id, the \c{namespace URI} and the \c{prefix} are undefined, and
1573 the \c{local name} is the ID that should be looked up.
1575 \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}
1579 \fn QVector<QXmlNodeModelIndex> QAbstractXmlNodeModel::nodesByIdref(const QXmlName &idref) const
1581 Returns the elements and/or attributes that have an \c IDREF value
1582 equal to \a idref. XQuery's \c idref() function calls this function.
1584 The implementor guarantees that the nodes identified by the returned
1585 indexes are elements or attributes.
1587 It is not sufficient for an attribute or element to merely be called
1588 \c idref. It must also be of type \c IDREF. Elements must be typed as
1589 \c xs:IDREF or \c xs:IDREFS, or, in the case of attributes, as \c
1590 IDREF or \c IDREFS in the schema.
1592 In \a idref, the \c{namespace URI} and the \c{prefix} are undefined,
1593 and the \c{local name} is the ID that should be looked up.
1595 \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}
1599 \fn QXmlName::NamespaceCode QXmlNodeModelIndex::namespaceForPrefix(const QXmlName::PrefixCode prefix) const
1604 \fn QString QXmlNodeModelIndex::stringValue() const
1609 \fn QPatternist::ItemTypePtr QXmlNodeModelIndex::type() const
1614 \fn bool QXmlNodeModelIndex::is(const QXmlNodeModelIndex &other) const
1619 \enum QAbstractXmlNodeModel::NodeCopySetting
1622 Controls how nodes are copied with copyNodeTo.
1624 \value InheritNamespaces Copies the node with the \c copy-namespaces
1625 setting being \c inherit. If not set, \c no-inherit is assumed.
1626 \value PreserveNamespaces Copies the node with the \c copy-namespaces
1627 settings being \c preserve. If not set, \c no-preserve is assumed.
1631 \typedef QAbstractXmlNodeModel::NodeCopySettings
1638 Copies node \a node to \a receiver, steered by \a copySettings.
1640 The caller guarantees that \a node is not \c null, and that is
1641 belongs to this QAbstractXmlNodeModel instance.
1643 The caller guarantees that \a receiver is not \c null.
1645 void QAbstractXmlNodeModel::copyNodeTo(const QXmlNodeModelIndex &node,
1646 QAbstractXmlReceiver *const receiver,
1647 const NodeCopySettings ©Settings) const
1651 Q_UNUSED(copySettings);
1652 Q_ASSERT_X(false, Q_FUNC_INFO,
1653 "This function is not expected to be called.");
1657 Returns the source location for the object with the given \a index
1658 or a default constructed QSourceLocation in case no location
1659 information is available.
1663 QSourceLocation QAbstractXmlNodeModel::sourceLocation(const QXmlNodeModelIndex &index) const
1665 // TODO: make this method virtual in Qt5 to allow source location support in custom models
1667 return d_ptr->sourceLocation(index);
1669 return QSourceLocation();