e8880b7a4a80d87ea470eadd68394f60b08bf1aa
[profile/ivi/qtxmlpatterns.git] / src / xmlpatterns / api / qabstractxmlreceiver.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtXmlPatterns module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include <QString>
43
44 #include "qitem_p.h"
45
46 #include "qabstractxmlreceiver_p.h"
47 #include "qabstractxmlreceiver.h"
48
49 QT_BEGIN_NAMESPACE
50
51 /*!
52   \class QAbstractXmlReceiver
53   \brief The QAbstractXmlReceiver class provides a callback interface
54          for transforming the output of a QXmlQuery.
55   \reentrant
56   \since 4.4
57   \ingroup xml-tools
58
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:
64
65   \snippet doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlreceiver.cpp 0
66
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}.
78
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}.
83
84   \target XQuery Sequence
85   \section1 XQuery Sequences
86
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.
90
91   There are six kinds of \e nodes.
92
93   \list
94
95   \li An \e {Element Node} represents an XML element.
96
97   \li An \e {Attribute Node} represents an XML attribute.
98
99   \li A \e {Document Node} represents an entire XML document.
100
101   \li A \e {Text Node} represents character data (element content).
102
103   \li 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.
109
110   \li And a \e {Comment node} represents an XML comment.
111
112   \endlist
113
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}.
117
118   \list
119
120   \li Each \e node appears in the \e sequence before its children
121   and their descendants appear.
122
123   \li A \e node's descendants appear in the \e sequence before
124   any of its siblings appear.
125
126   \li 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.
130
131   \li \e {Namespace Nodes} immediately follow the \e {Element Node}
132    with which they are associated.
133
134   \li \e {Attribute Nodes} immediately follow the \e {Namespace Nodes}
135    of the element with which they are associated, or...
136
137    \li If there are no \e {Namespace Nodes} following an element, then
138    the \e {Attribute Nodes} immediately follow the element.
139
140    \li 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.
142
143    \li \e {Processing Instruction Nodes} do not have children, and
144    their parent is either a \e {Document Node} or an \e {Element
145    Node}.
146
147    \li \e {Comment Nodes} do not have children, and
148    their parent is either a \e {Document Node} or an \e {Element
149    Node}.
150
151   \endlist
152
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.
158
159   \list
160
161   \li 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.
165
166   \li 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.
169
170   \li attribute() is called for each \e {Attribute Node}.
171
172   \li comment() is called for each \e {Comment Node}.
173
174   \li characters() is called for each \e {Text Node}.
175
176   \li processingInstruction() is called for each \e {Processing
177   Instruction Node}.
178
179   \li namespaceBinding() is called for each \e {Namespace Node}.
180
181   \li atomicValue() is called for each \e {atomic value}.
182
183   \endlist
184
185   For a complete explanation of XQuery sequences, visit
186   \l {http://www.w3.org/TR/xpath-datamodel/}{XQuery Data Model}.
187
188   \sa {http://www.w3.org/TR/xpath-datamodel/}{W3C XQuery 1.0 and XPath 2.0 Data Model (XDM)}
189   \sa QXmlSerializer
190   \sa QXmlResultItems
191  */
192
193 template<const QXmlNodeModelIndex::Axis axis>
194 void QAbstractXmlReceiver::sendFromAxis(const QXmlNodeModelIndex &node)
195 {
196     Q_ASSERT(!node.isNull());
197     const QXmlNodeModelIndex::Iterator::Ptr it(node.iterate(axis));
198     QXmlNodeModelIndex next(it->next());
199
200     while(!next.isNull())
201     {
202         sendAsNode(next);
203         next = it->next();
204     }
205 }
206
207 /*!
208  \internal
209  */
210 QAbstractXmlReceiver::QAbstractXmlReceiver(QAbstractXmlReceiverPrivate *d)
211   : d_ptr(d)
212 {
213 }
214
215 /*!
216   Constructs an abstract xml receiver.
217  */
218 QAbstractXmlReceiver::QAbstractXmlReceiver() : d_ptr(0)
219 {
220 }
221
222 /*!
223   Destroys the xml receiver.
224  */
225 QAbstractXmlReceiver::~QAbstractXmlReceiver()
226 {
227 }
228
229 /*!
230   \fn void QAbstractXmlReceiver::startElement(const QXmlName &name)
231
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.
235  */
236
237 /*
238 ### Qt 5:
239
240 Consider how source locations should be communicated. Maybe every signature
241 should be extended by adding "qint64 line = -1, qint64 column = -1".
242  */
243
244 /*!
245   \fn void QAbstractXmlReceiver::endElement()
246
247   This callback is called when the end of an element node
248   appears in the \l {XQuery Sequence} {sequence}.
249 */
250
251 /*!
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.
258  */
259
260 /*!
261   \fn void QAbstractXmlReceiver::comment(const QString &value)
262
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
266   "--".
267  */
268
269 /*!
270   \fn void QAbstractXmlReceiver::characters(const QStringRef &value)
271
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.
277  */
278
279 /*!
280   \fn void QAbstractXmlReceiver::startDocument()
281
282   This callback is called when a document node appears
283   in the \l {XQuery Sequence} {sequence}.
284  */
285
286 /*
287 ### Qt 5:
288
289 Change
290     virtual void startDocument() = 0;
291
292 To:
293     virtual void startDocument(const QUrl &uri) = 0;
294
295 Such that it allows the document URI to be communicated. The contract would
296 allow null QUrls.
297 */
298
299 /*!
300   \fn void QAbstractXmlReceiver::endDocument()
301
302   This callback is called when the end of a document node
303   appears in the \l {XQuery Sequence} {sequence}.
304  */
305
306 /*!
307   \fn void QAbstractXmlReceiver::processingInstruction(const QXmlName &target,
308                                                        const QString &value)
309
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.
317
318   \quotefile doc/src/snippets/patternist/xmlStylesheet.xq
319
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}.
324
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}.
328
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.
333  */
334
335 /*!
336   \fn void QAbstractXmlReceiver::atomicValue(const QVariant &value)
337
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()}
341   {valid}.
342  */
343
344 /*!
345   \fn virtual void QAbstractXmlReceiver::namespaceBinding(const QXmlName &name)
346
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.
352  */
353
354 /*!
355   \internal
356
357    Treats \a outputItem as a node and calls the appropriate function,
358    e.g., attribute() or comment(), depending on its
359    QXmlNodeModelIndex::NodeKind.
360
361    This is a helper function that subclasses can use to multiplex
362    Nodes received via item().
363  */
364 void QAbstractXmlReceiver::sendAsNode(const QPatternist::Item &outputItem)
365 {
366     Q_ASSERT(outputItem);
367     Q_ASSERT(outputItem.isNode());
368     const QXmlNodeModelIndex asNode = outputItem.asNode();
369
370     switch(asNode.kind())
371     {
372         case QXmlNodeModelIndex::Attribute:
373         {
374             const QString &v = outputItem.stringValue();
375             attribute(asNode.name(), QStringRef(&v));
376             return;
377         }
378         case QXmlNodeModelIndex::Element:
379         {
380             startElement(asNode.name());
381
382             /* First the namespaces, then attributes, then the children. */
383             asNode.sendNamespaces(this);
384             sendFromAxis<QXmlNodeModelIndex::AxisAttribute>(asNode);
385             sendFromAxis<QXmlNodeModelIndex::AxisChild>(asNode);
386
387             endElement();
388
389             return;
390         }
391         case QXmlNodeModelIndex::Text:
392         {
393             const QString &v = asNode.stringValue();
394             characters(QStringRef(&v));
395             return;
396         }
397         case QXmlNodeModelIndex::ProcessingInstruction:
398         {
399             processingInstruction(asNode.name(), outputItem.stringValue());
400             return;
401         }
402         case QXmlNodeModelIndex::Comment:
403         {
404             comment(outputItem.stringValue());
405             return;
406         }
407         case QXmlNodeModelIndex::Document:
408         {
409             startDocument();
410             sendFromAxis<QXmlNodeModelIndex::AxisChild>(asNode);
411             endDocument();
412             return;
413         }
414         case QXmlNodeModelIndex::Namespace:
415             Q_ASSERT_X(false, Q_FUNC_INFO, "Not implemented");
416     }
417
418     Q_ASSERT_X(false, Q_FUNC_INFO,
419                QString::fromLatin1("Unknown node type: %1").arg(asNode.kind()).toUtf8().constData());
420 }
421
422 /*!
423   \internal
424
425    This function may be called instead of characters() if, and only if,
426    \a value consists only of whitespace.
427
428    The caller gurantees that \a value is not empty.
429
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.
433
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().
438
439    \sa characters()
440  */
441 void QAbstractXmlReceiver::whitespaceOnly(const QStringRef &value)
442 {
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));
447 }
448
449 /*!
450   \internal
451  */
452 void QAbstractXmlReceiver::item(const QPatternist::Item &item)
453 {
454     if(item.isNode())
455         return sendAsNode(item);
456     else
457         atomicValue(QPatternist::AtomicValue::toQt(item.asAtomicValue()));
458 }
459
460 /*!
461  \fn void QAbstractXmlReceiver::startOfSequence()
462
463  This callback is called once only, right before the
464  \l {XQuery Sequence} {sequence} begins.
465  */
466
467 /*!
468   \fn void QAbstractXmlReceiver::endOfSequence()
469
470  This callback is called once only, right after the
471  \l {XQuery Sequence} {sequence} ends.
472  */
473
474 QT_END_NAMESPACE
475