1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtXmlPatterns module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qdocumentprojector_p.h"
46 using namespace QPatternist;
48 DocumentProjector::DocumentProjector(const ProjectedExpression::Vector &paths,
49 QAbstractXmlReceiver *const receiver) : m_paths(paths)
50 , m_pathCount(paths.count())
51 , m_action(ProjectedExpression::Move)
53 , m_receiver(receiver)
55 Q_ASSERT_X(paths.count() > 0, Q_FUNC_INFO,
56 "Using DocumentProjector with no paths is an "
57 "overhead and has also undefined behavior.");
61 void DocumentProjector::startElement(const QXmlName name)
67 case ProjectedExpression::KeepSubtree:
69 m_receiver->startElement(name);
72 case ProjectedExpression::Skip:
79 Q_ASSERT_X(m_action == ProjectedExpression::Move, Q_FUNC_INFO,
80 "We're not supposed to receive Keep here, because "
81 "endElement() should always end that state.");
83 for(int i = 0; i < m_pathCount; ++i)
85 m_action = m_paths.at(i)->actionForElement(name, m_paths[i]);
89 case ProjectedExpression::Keep:
91 m_action = ProjectedExpression::Keep;
94 case ProjectedExpression::KeepSubtree:
96 /* Ok, at least one path wanted this node. Pass it on,
98 m_receiver->startElement(name);
102 case ProjectedExpression::Skip:
104 /* This particular path doesn't need it, but
105 * some other path might, so continue looping. */
108 case ProjectedExpression::Move:
109 Q_ASSERT_X(false, Q_FUNC_INFO, "The action functions can never return Move.");
115 if(m_action == ProjectedExpression::Keep)
116 m_receiver->startElement(name);
119 Q_ASSERT(m_action == ProjectedExpression::Skip);
125 void DocumentProjector::endElement()
127 if(m_action == ProjectedExpression::Keep)
129 Q_ASSERT(m_nodesInProcess == 1);
131 m_receiver->endElement();
133 /* We have now kept the single node, and now wants to skip
134 * all its children. */
135 m_action = ProjectedExpression::Skip;
136 m_nodesInProcess = 0;
138 else if(m_action == ProjectedExpression::KeepSubtree)
140 m_receiver->endElement();
143 if(m_nodesInProcess == 0)
145 /* We have now skipped all the children, let's do
146 * a new path analysis. */
147 m_action = ProjectedExpression::Move;
152 Q_ASSERT_X(m_action == ProjectedExpression::Skip, Q_FUNC_INFO,
153 "We're not supposed to be in a Move action here.");
154 /* We skip calling m_receiver's endElement() here since we're
156 Q_ASSERT(m_nodesInProcess > 0);
159 if(m_nodesInProcess == 0)
161 /* Ok, we've skipped them all, let's do something
162 * new -- let's Move on to the next path! */
163 m_action = ProjectedExpression::Move;
168 void DocumentProjector::attribute(const QXmlName name,
169 const QString &value)
175 void DocumentProjector::namespaceBinding(const QXmlName nb)
180 void DocumentProjector::comment(const QString &value)
182 Q_ASSERT_X(!value.contains(QLatin1String("--")), Q_FUNC_INFO,
183 "Invalid input; it's the caller's responsibility to ensure the input is correct.");
187 void DocumentProjector::characters(const QString &value)
192 void DocumentProjector::processingInstruction(const QXmlName name,
193 const QString &value)
195 Q_ASSERT_X(!value.contains(QLatin1String("?>")), Q_FUNC_INFO,
196 "Invalid input; it's the caller's responsibility to ensure the input is correct.");
201 void DocumentProjector::item(const Item &outputItem)
203 Q_UNUSED(outputItem);
206 void DocumentProjector::startDocument()
210 void DocumentProjector::endDocument()