1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtXmlPatterns module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include <QVariant>
41
42#include "qabstractxmlnodemodel_p.h"
43#include "qitemmappingiterator_p.h"
44#include "qitem_p.h"
45#include "qxmlname.h"
46#include "qxmlquery_p.h"
47
48#include "qpullbridge_p.h"
49
50QT_BEGIN_NAMESPACE
51
52using namespace QPatternist;
53
54/*!
55 \brief Bridges a QPatternist::SequenceIterator to QAbstractXmlPullProvider.
56 \class QPatternist::PullBridge
57 \internal
58 \reentrant
59 \ingroup xml-tools
60
61 The approach of this class is rather straight forward since QPatternist::SequenceIterator
62 and QAbstractXmlPullProvider are conceptually similar. While QPatternist::SequenceIterator only
63 delivers top level items(since it's not an event stream, it's a list of items), PullBridge
64 needs to recursively iterate the children of nodes too, which is achieved through the
65 stack m_iterators.
66 */
67
68AbstractXmlPullProvider::Event PullBridge::next()
69{
70 m_index = m_iterators.top().second->next();
71
72 if(!m_index.isNull())
73 {
74 Item item(m_index);
75
76 if(item && item.isAtomicValue())
77 m_current = AtomicValue;
78 else
79 {
80 Q_ASSERT(item.isNode());
81
82 switch(m_index.kind())
83 {
84 case QXmlNodeModelIndex::Attribute:
85 {
86 m_current = Attribute;
87 break;
88 }
89 case QXmlNodeModelIndex::Comment:
90 {
91 m_current = Comment;
92 break;
93 }
94 case QXmlNodeModelIndex::Element:
95 {
96 m_iterators.push(t: qMakePair(x: StartElement, y: m_index.iterate(axis: QXmlNodeModelIndex::AxisChild)));
97 m_current = StartElement;
98 break;
99 }
100 case QXmlNodeModelIndex::Document:
101 {
102 m_iterators.push(t: qMakePair(x: StartDocument, y: m_index.iterate(axis: QXmlNodeModelIndex::AxisChild)));
103 m_current = StartDocument;
104 break;
105 }
106 case QXmlNodeModelIndex::Namespace:
107 {
108 m_current = Namespace;
109 break;
110 }
111 case QXmlNodeModelIndex::ProcessingInstruction:
112 {
113 m_current = ProcessingInstruction;
114 break;
115 }
116 case QXmlNodeModelIndex::Text:
117 {
118 m_current = Text;
119 break;
120 }
121 }
122 }
123 }
124 else
125 {
126 if(m_iterators.isEmpty())
127 m_current = EndOfInput;
128 else
129 {
130 switch(m_iterators.top().first)
131 {
132 case StartOfInput:
133 {
134 m_current = EndOfInput;
135 break;
136 }
137 case StartElement:
138 {
139 m_current = EndElement;
140 m_iterators.pop();
141 break;
142 }
143 case StartDocument:
144 {
145 m_current = EndDocument;
146 m_iterators.pop();
147 break;
148 }
149 default:
150 {
151 Q_ASSERT_X(false, Q_FUNC_INFO,
152 "Invalid value.");
153 m_current = EndOfInput;
154 }
155 }
156 }
157
158 }
159
160 return m_current;
161}
162
163AbstractXmlPullProvider::Event PullBridge::current() const
164{
165 return m_current;
166}
167
168QXmlNodeModelIndex PullBridge::index() const
169{
170 return m_index;
171}
172
173QSourceLocation PullBridge::sourceLocation() const
174{
175 return m_index.model()->sourceLocation(index: m_index);
176}
177
178QXmlName PullBridge::name() const
179{
180 return m_index.name();
181}
182
183QVariant PullBridge::atomicValue() const
184{
185 return QVariant();
186}
187
188QString PullBridge::stringValue() const
189{
190 return QString();
191}
192
193QHash<QXmlName, QString> PullBridge::attributes()
194{
195 Q_ASSERT(m_current == StartElement);
196
197 QHash<QXmlName, QString> attributes;
198
199 QXmlNodeModelIndex::Iterator::Ptr it = m_index.iterate(axis: QXmlNodeModelIndex::AxisAttribute);
200 QXmlNodeModelIndex index = it->next();
201 while (!index.isNull()) {
202 const Item attribute(index);
203 attributes.insert(akey: index.name(), avalue: index.stringValue());
204
205 index = it->next();
206 }
207
208 return attributes;
209}
210
211QHash<QXmlName, QXmlItem> PullBridge::attributeItems()
212{
213 Q_ASSERT(m_current == StartElement);
214
215 QHash<QXmlName, QXmlItem> attributes;
216
217 QXmlNodeModelIndex::Iterator::Ptr it = m_index.iterate(axis: QXmlNodeModelIndex::AxisAttribute);
218 QXmlNodeModelIndex index = it->next();
219 while (!index.isNull()) {
220 const Item attribute(index);
221 attributes.insert(akey: index.name(), avalue: QXmlItem(index));
222
223 index = it->next();
224 }
225
226 return attributes;
227}
228
229QT_END_NAMESPACE
230
231

source code of qtxmlpatterns/src/xmlpatterns/api/qpullbridge.cpp