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 ****************************************************************************/
46 #include "qabstractxmlreceiver_p.h"
47 #include "qabstractxmlreceiver.h"
52 \class QAbstractXmlReceiver
53 \brief The QAbstractXmlReceiver class provides a callback interface
54 for transforming the output of a QXmlQuery.
59 QAbstractXmlReceiver is an abstract base class that provides
60 a callback interface for receiving an \l {XQuery Sequence}
61 {XQuery sequence}, usually the output of an QXmlQuery, and
62 transforming that sequence into a structure of your choosing,
63 usually XML. Consider the example:
65 \snippet doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlreceiver.cpp 0
67 First it constructs a \l {QXmlQuery} {query} that gets the
68 first paragraph from document \c index.html. Then it constructs
69 an \l {QXmlSerializer} {XML serializer} with the \l {QXmlQuery}
70 {query} and \l {QIODevice} {myOutputDevice} (Note the
71 \l {QXmlSerializer} {serializer} is an \e {XML receiver},
72 ie a subclass of QAbstractXmlReceiver). Finally, it
73 \l {QXmlQuery::evaluateTo()} {evaluates} the
74 \l {QXmlQuery} {query}, producing an ordered sequence of calls
75 to the \l {QXmlSerializer} {serializer's} callback functions.
76 The sequence of callbacks transforms the query output to XML
77 and writes it to \l {QIODevice} {myOutputDevice}.
79 Although the example uses \l {QXmlQuery} to produce the sequence
80 of callbacks to functions in QAbstractXmlReceiver, you can call
81 the callback functions directly as long as your sequence of
82 calls represents a valid \l {XQuery Sequence} {XQuery sequence}.
84 \target XQuery Sequence
85 \section1 XQuery Sequences
87 An XQuery \a sequence is an ordered collection of zero, one,
88 or many \e items. Each \e item is either an \e {atomic value}
89 or a \e {node}. An \e {atomic value} is a simple data value.
91 There are six kinds of \e nodes.
95 \o An \e {Element Node} represents an XML element.
97 \o An \e {Attribute Node} represents an XML attribute.
99 \o A \e {Document Node} represents an entire XML document.
101 \o A \e {Text Node} represents character data (element content).
103 \o A \e {Processing Instruction Node} represents an XML
104 processing instruction, which is used in an XML document
105 to tell the application reading the document to perform
106 some action. A typical example is to use a processing
107 instruction to tell the application to use a particular
108 XSLT stylesheet to display the document.
110 \o And a \e {Comment node} represents an XML comment.
114 The \e sequence of \e nodes and \e {atomic values} obeys
115 the following rules. Note that \e {Namespace Node} refers
116 to a special \e {Attribute Node} with name \e {xmlns}.
120 \o Each \e node appears in the \e sequence before its children
121 and their descendants appear.
123 \o A \e node's descendants appear in the \e sequence before
124 any of its siblings appear.
126 \o A \e {Document Node} represents an entire document. Zero or
127 more \e {Document Nodes} can appear in a \e sequence, but they
128 can only be top level items (i.e., a \e {Document Node} can't
129 be a child of another \e node.
131 \o \e {Namespace Nodes} immediately follow the \e {Element Node}
132 with which they are associated.
134 \o \e {Attribute Nodes} immediately follow the \e {Namespace Nodes}
135 of the element with which they are associated, or...
137 \o If there are no \e {Namespace Nodes} following an element, then
138 the \e {Attribute Nodes} immediately follow the element.
140 \o An \e {atomic value} can only appear as a top level \e item,
141 i.e., it can't appear as a child of a \e node.
143 \o \e {Processing Instruction Nodes} do not have children, and
144 their parent is either a \e {Document Node} or an \e {Element
147 \o \e {Comment Nodes} do not have children, and
148 their parent is either a \e {Document Node} or an \e {Element
153 The \e sequence of \e nodes and \e {atomic values} is sent to
154 an QAbstractXmlReceiver (QXmlSerializer in
155 the example above) as a sequence of calls to the receiver's
156 callback functions. The mapping of callback functions to
157 sequence items is as follows.
161 \o startDocument() and endDocument() are called for each
162 \e {Document Node} in the \e sequence. endDocument() is not
163 called until all the \e {Document Node's} children have
164 appeared in the \e sequence.
166 \o startElement() and endElement() are called for each
167 \e {Element Node}. endElement() is not called until all the
168 \e {Element Node's} children have appeared in the \e sequence.
170 \o attribute() is called for each \e {Attribute Node}.
172 \o comment() is called for each \e {Comment Node}.
174 \o characters() is called for each \e {Text Node}.
176 \o processingInstruction() is called for each \e {Processing
179 \o namespaceBinding() is called for each \e {Namespace Node}.
181 \o atomicValue() is called for each \e {atomic value}.
185 For a complete explanation of XQuery sequences, visit
186 \l {http://www.w3.org/TR/xpath-datamodel/}{XQuery Data Model}.
188 \sa {http://www.w3.org/TR/xpath-datamodel/}{W3C XQuery 1.0 and XPath 2.0 Data Model (XDM)}
193 template<const QXmlNodeModelIndex::Axis axis>
194 void QAbstractXmlReceiver::sendFromAxis(const QXmlNodeModelIndex &node)
196 Q_ASSERT(!node.isNull());
197 const QXmlNodeModelIndex::Iterator::Ptr it(node.iterate(axis));
198 QXmlNodeModelIndex next(it->next());
200 while(!next.isNull())
210 QAbstractXmlReceiver::QAbstractXmlReceiver(QAbstractXmlReceiverPrivate *d)
216 Constructs an abstract xml receiver.
218 QAbstractXmlReceiver::QAbstractXmlReceiver() : d_ptr(0)
223 Destroys the xml receiver.
225 QAbstractXmlReceiver::~QAbstractXmlReceiver()
230 \fn void QAbstractXmlReceiver::startElement(const QXmlName &name)
232 This callback is called when a new element node appears
233 in the \l {XQuery Sequence} {sequence}. \a name is the
234 valid \l {QXmlName} {name} of the node element.
240 Consider how source locations should be communicated. Maybe every signature
241 should be extended by adding "qint64 line = -1, qint64 column = -1".
245 \fn void QAbstractXmlReceiver::endElement()
247 This callback is called when the end of an element node
248 appears in the \l {XQuery Sequence} {sequence}.
252 \fn void QAbstractXmlReceiver::attribute(const QXmlName &name,
253 const QStringRef &value)
254 This callback is called when an attribute node
255 appears in the \l {XQuery Sequence} {sequence}.
256 \a name is the \l {QXmlName} {attribute name} and
257 the \a value string contains the attribute value.
261 \fn void QAbstractXmlReceiver::comment(const QString &value)
263 This callback is called when a comment node appears
264 in the \l {XQuery Sequence} {sequence}. The \a value
265 is the comment text, which must not contain the string
270 \fn void QAbstractXmlReceiver::characters(const QStringRef &value)
272 This callback is called when a text node appears in the
273 \l {XQuery Sequence} {sequence}. The \a value contains
274 the text. Adjacent text nodes may not occur in the
275 \l {XQuery Sequence} {sequence}, i.e., this callback must not
276 be called twice in a row.
280 \fn void QAbstractXmlReceiver::startDocument()
282 This callback is called when a document node appears
283 in the \l {XQuery Sequence} {sequence}.
290 virtual void startDocument() = 0;
293 virtual void startDocument(const QUrl &uri) = 0;
295 Such that it allows the document URI to be communicated. The contract would
300 \fn void QAbstractXmlReceiver::endDocument()
302 This callback is called when the end of a document node
303 appears in the \l {XQuery Sequence} {sequence}.
307 \fn void QAbstractXmlReceiver::processingInstruction(const QXmlName &target,
308 const QString &value)
310 This callback is called when a processing instruction
311 appears in the \l {XQuery Sequence} {sequence}.
312 A processing instruction is used in an XML document
313 to tell the application reading the document to
314 perform some action. A typical example is to use a
315 processing instruction to tell the application to use a
316 particular XSLT stylesheet to process the document.
318 \quotefile doc/src/snippets/patternist/xmlStylesheet.xq
320 \a target is the \l {QXmlName} {name} of the processing
321 instruction. Its \e prefix and \e {namespace URI} must both
322 be empty. Its \e {local name} is the target. In the above
323 example, the name is \e {xml-stylesheet}.
325 The \a value specifies the action to be taken. Note that
326 the \a value must not contain the string "?>". In the above
327 example, the \a value is \e{type="test/xsl" href="formatter.xsl}.
329 Generally, use of processing instructions should be avoided,
330 because they are not namespace aware and in many contexts
331 are stripped out anyway. Processing instructions can often
332 be replaced with elements from a custom namespace.
336 \fn void QAbstractXmlReceiver::atomicValue(const QVariant &value)
338 This callback is called when an atomic value appears in the \l
339 {XQuery Sequence} {sequence}. The \a value is a simple \l {QVariant}
340 {data value}. It is guaranteed to be \l {QVariant::isValid()}
345 \fn virtual void QAbstractXmlReceiver::namespaceBinding(const QXmlName &name)
347 This callback is called when a namespace binding is in scope of an
348 element. A namespace is defined by a URI. In the \l {QXmlName}
349 \a name, the value of \l {QXmlName::namespaceUri()} is that URI. The
350 value of \l {QXmlName::prefix()} is the prefix that the URI is bound
351 to. The local name is insignificant and can be an arbitrary value.
357 Treats \a outputItem as a node and calls the appropriate function,
358 e.g., attribute() or comment(), depending on its
359 QXmlNodeModelIndex::NodeKind.
361 This is a helper function that subclasses can use to multiplex
362 Nodes received via item().
364 void QAbstractXmlReceiver::sendAsNode(const QPatternist::Item &outputItem)
366 Q_ASSERT(outputItem);
367 Q_ASSERT(outputItem.isNode());
368 const QXmlNodeModelIndex asNode = outputItem.asNode();
370 switch(asNode.kind())
372 case QXmlNodeModelIndex::Attribute:
374 const QString &v = outputItem.stringValue();
375 attribute(asNode.name(), QStringRef(&v));
378 case QXmlNodeModelIndex::Element:
380 startElement(asNode.name());
382 /* First the namespaces, then attributes, then the children. */
383 asNode.sendNamespaces(this);
384 sendFromAxis<QXmlNodeModelIndex::AxisAttribute>(asNode);
385 sendFromAxis<QXmlNodeModelIndex::AxisChild>(asNode);
391 case QXmlNodeModelIndex::Text:
393 const QString &v = asNode.stringValue();
394 characters(QStringRef(&v));
397 case QXmlNodeModelIndex::ProcessingInstruction:
399 processingInstruction(asNode.name(), outputItem.stringValue());
402 case QXmlNodeModelIndex::Comment:
404 comment(outputItem.stringValue());
407 case QXmlNodeModelIndex::Document:
410 sendFromAxis<QXmlNodeModelIndex::AxisChild>(asNode);
414 case QXmlNodeModelIndex::Namespace:
415 Q_ASSERT_X(false, Q_FUNC_INFO, "Not implemented");
418 Q_ASSERT_X(false, Q_FUNC_INFO,
419 QString::fromLatin1("Unknown node type: %1").arg(asNode.kind()).toUtf8().constData());
425 This function may be called instead of characters() if, and only if,
426 \a value consists only of whitespace.
428 The caller gurantees that \a value is not empty.
430 \e Whitespace refers to a sequence of characters that are either
431 spaces, tabs, or newlines, in any order. In other words, not all
432 the Unicode whitespace category is considered whitespace here.
434 However, there is no guarantee or requirement that whitespaceOnly()
435 is called for text nodes containing whitespace only. characters()
436 may be called just as well. This is why the default implementation
437 for whitespaceOnly() calls characters().
441 void QAbstractXmlReceiver::whitespaceOnly(const QStringRef &value)
443 Q_ASSERT_X(value.toString().trimmed().isEmpty(), Q_FUNC_INFO,
444 "The caller must guarantee only whitespace is passed. Use characters() in other cases.");
445 const QString &v = value.toString();
446 characters(QStringRef(&v));
452 void QAbstractXmlReceiver::item(const QPatternist::Item &item)
455 return sendAsNode(item);
457 atomicValue(QPatternist::AtomicValue::toQt(item.asAtomicValue()));
461 \fn void QAbstractXmlReceiver::startOfSequence()
463 This callback is called once only, right before the
464 \l {XQuery Sequence} {sequence} begins.
468 \fn void QAbstractXmlReceiver::endOfSequence()
470 This callback is called once only, right after the
471 \l {XQuery Sequence} {sequence} ends.