Qt 4.8
qmaintainingreader.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
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 Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
49 template<typename TokenLookupClass,
50  typename LookupKey>
52  const QSet<typename TokenLookupClass::NodeName> &standardAttributes,
53  const ReportContext::Ptr &context,
54  QIODevice *const queryDevice) : QXmlStreamReader(queryDevice)
55  , m_hasHandledStandardAttributes(false)
56  , m_context(context)
57  , m_elementDescriptions(elementDescriptions)
58  , m_standardAttributes(standardAttributes)
59 {
60  Q_ASSERT(m_context);
61  Q_ASSERT(!m_elementDescriptions.isEmpty());
62 
63  /* We start with stripping. */
64  m_stripWhitespace.push(true);
65 }
66 
67 template<typename TokenLookupClass,
68  typename LookupKey>
70 {
71 }
72 
73 template<typename TokenLookupClass,
74  typename LookupKey>
76 {
77  return QSourceLocation(documentURI(),
78  lineNumber(),
79  columnNumber());
80 }
81 
82 template<typename TokenLookupClass,
83  typename LookupKey>
85 {
86  const TokenType retval = QXmlStreamReader::readNext();
87 
88  switch(retval)
89  {
90  case StartElement:
91  {
92  m_currentElementName = TokenLookupClass::toToken(name());
93  m_currentAttributes = attributes();
94  m_hasHandledStandardAttributes = false;
95 
96  if(!m_currentAttributes.hasAttribute(QLatin1String("xml:space")))
97  m_stripWhitespace.push(m_stripWhitespace.top());
98  break;
99  }
100  case EndElement:
101  m_currentElementName = TokenLookupClass::toToken(name());
102  m_stripWhitespace.pop();
103  break;
104  default:
105  break;
106  }
107 
108  return retval;
109 }
110 
111 template<typename TokenLookupClass,
112  typename LookupKey>
114 {
116  || XPathHelper::isWhitespaceOnly(text());
117 }
118 
119 
120 template<typename TokenLookupClass,
121  typename LookupKey>
123  const ReportContext::ErrorCode code) const
124 {
125  m_context->error(message, code, currentLocation());
126 }
127 
128 template<typename TokenLookupClass,
129  typename LookupKey>
131 {
132  m_context->warning(message, currentLocation());
133 }
134 
135 template<typename TokenLookupClass,
136  typename LookupKey>
138 {
139  return m_currentElementName;
140 }
141 
142 template<typename TokenLookupClass,
143  typename LookupKey>
145 {
147 
148  if(m_elementDescriptions.contains(elementName))
149  {
150  // QHash::value breaks in Metrowerks Compiler
151  const ElementDescription<TokenLookupClass, LookupKey> &desc = *m_elementDescriptions.find(elementName);
152  const int attCount = m_currentAttributes.count();
153 
154  QSet<typename TokenLookupClass::NodeName> encounteredXSLTAtts;
155 
156  for(int i = 0; i < attCount; ++i)
157  {
158  const QXmlStreamAttribute &attr = m_currentAttributes.at(i);
159  if(attr.namespaceUri().isEmpty())
160  {
161  const typename TokenLookupClass::NodeName attrName(TokenLookupClass::toToken(attr.name()));
162  encounteredXSLTAtts.insert(attrName);
163 
164  if(!desc.requiredAttributes.contains(attrName) &&
165  !desc.optionalAttributes.contains(attrName) &&
166  !m_standardAttributes.contains(attrName) &&
167  !isAnyAttributeAllowed())
168  {
169  QString translationString;
170 
172  const int totalCount = all.count();
173  QStringList allowed;
174 
175  for(int i = 0; i < totalCount; ++i)
177 
178  /* Note, we can't run toString() on attrName, because we're in this branch,
179  * the token lookup doesn't have the string(!).*/
180  const QString stringedName(attr.name().toString());
181 
182  if(totalCount == 0)
183  {
184  translationString = QtXmlPatterns::tr("Attribute %1 cannot appear on the element %2. Only the standard attributes can appear.")
185  .arg(formatKeyword(stringedName),
186  formatKeyword(name()));
187  }
188  else if(totalCount == 1)
189  {
190  translationString = QtXmlPatterns::tr("Attribute %1 cannot appear on the element %2. Only %3 is allowed, and the standard attributes.")
191  .arg(formatKeyword(stringedName),
192  formatKeyword(name()),
193  allowed.first());
194  }
195  else if(totalCount == 1)
196  {
197  /* Note, allowed has already had formatKeyword() applied. */
198  translationString = QtXmlPatterns::tr("Attribute %1 cannot appear on the element %2. Allowed is %3, %4, and the standard attributes.")
199  .arg(formatKeyword(stringedName),
200  formatKeyword(name()),
201  allowed.first(),
202  allowed.last());
203  }
204  else
205  {
206  /* Note, allowed has already had formatKeyword() applied. */
207  translationString = QtXmlPatterns::tr("Attribute %1 cannot appear on the element %2. Allowed is %3, and the standard attributes.")
208  .arg(formatKeyword(stringedName),
209  formatKeyword(name()),
210  allowed.join(QLatin1String(", ")));
211  }
212 
213  m_context->error(translationString,
214  ReportContext::XTSE0090,
215  currentLocation());
216  }
217  }
218  else if(attr.namespaceUri() == namespaceUri())
219  {
220  m_context->error(QtXmlPatterns::tr("XSL-T attributes on XSL-T elements must be in the null namespace, not in the XSL-T namespace which %1 is.")
221  .arg(formatKeyword(attr.name())),
222  ReportContext::XTSE0090,
223  currentLocation());
224  }
225  /* Else, attributes in other namespaces are allowed, continue. */
226  }
227 
229 
230  if(!requiredButMissing.isEmpty())
231  {
232  error(QtXmlPatterns::tr("The attribute %1 must appear on element %2.")
233  .arg(QPatternist::formatKeyword(TokenLookupClass::toString(*requiredButMissing.constBegin())),
234  formatKeyword(name())),
235  ReportContext::XTSE0010);
236  }
237  }
238  else
239  {
240  error(QtXmlPatterns::tr("The element with local name %1 does not exist in XSL-T.").arg(formatKeyword(name())),
241  ReportContext::XTSE0010);
242  }
243 }
244 
245 template<typename TokenLookupClass,
246  typename LookupKey>
248  const QString &localName) const
249 {
251  return m_currentAttributes.hasAttribute(namespaceURI, localName);
252 }
253 
254 template<typename TokenLookupClass,
255  typename LookupKey>
257 {
258  return hasAttribute(QString(), localName);
259 }
260 
261 template<typename TokenLookupClass,
262  typename LookupKey>
264  const QString &namespaceURI) const
265 {
267 
268  Q_ASSERT_X(m_currentAttributes.hasAttribute(namespaceURI, localName),
269  Q_FUNC_INFO,
270  "Validation must be done before this function is called.");
271 
272  return m_currentAttributes.value(namespaceURI, localName).toString();
273 }
274 
void warning(const QString &message) const
Convenience function for calling ReportContext::warning().
QString toString() const
Returns a copy of the string reference as a QString object.
Definition: qstring.cpp:8653
QString formatKeyword(const QString &keyword)
#define error(msg)
The QExplicitlySharedDataPointer class represents a pointer to an explicitly shared object...
Definition: qshareddata.h:136
static bool isWhitespace(char c)
The QString class provides a Unicode character string.
Definition: qstring.h:83
The QHash class is a template class that provides a hash-table-based dictionary.
Definition: qdatastream.h:66
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
TokenType
This enum specifies the type of token the reader just read.
Definition: qxmlstream.h:293
The QXmlStreamAttribute class represents a single XML attribute.
Definition: qxmlstream.h:135
static QString toString(Register *reg, int type, bool *ok=0)
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
bool contains(const T &value) const
Definition: qset.h:91
QList< T > toList() const
Definition: qset.h:296
const char * name
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
bool isEmpty() const
Returns true if the string reference has no characters; otherwise returns false.
Definition: qstring.h:1169
const_iterator insert(const T &value)
Definition: qset.h:179
The QSourceLocation class identifies a location in a resource by URI, line, and column.
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal...
Definition: qstring.h:654
QStringRef name() const
Returns the attribute&#39;s local name.
Definition: qxmlstream.h:149
Base class for tokenizers that reads XML formats. This is XSLTTokenizer, and the W3C XML Schema parse...
QSet< T > & subtract(const QSet< T > &other)
Definition: qset.h:270
TokenType readNext()
Reads the next token and returns its type.
Definition: qxmlstream.cpp:623
T & first()
Returns a reference to the first item in the list.
Definition: qlist.h:282
QString join(const QString &sep) const
Joins all the string list&#39;s strings into a single string with each element separated by the given sep...
Definition: qstringlist.h:162
#define Q_ASSERT_X(cond, where, what)
Definition: qglobal.h:1837
QString arg(qlonglong a, int fieldwidth=0, int base=10, const QChar &fillChar=QLatin1Char(' ')) const Q_REQUIRED_RESULT
Definition: qstring.cpp:7186
T & last()
Returns a reference to the last item in the list.
Definition: qlist.h:284
bool isWhitespace() const
Returns true if the reader reports characters that only consist of white-space; otherwise returns fal...
QSet< typename TokenLookupClass::NodeName > requiredAttributes
QSet< typename TokenLookupClass::NodeName > optionalAttributes
The QXmlStreamReader class provides a fast parser for reading well-formed XML via a simple streaming ...
Definition: qxmlstream.h:290
A structure that lists the optional and required attributes of an element. Used with MaintainingReade...
The QIODevice class is the base interface class of all I/O devices in Qt.
Definition: qiodevice.h:66
#define text
Definition: qobjectdefs.h:80
The QList class is a template class that provides lists.
Definition: qdatastream.h:62
#define Q_FUNC_INFO
Definition: qglobal.h:1871
QStringRef namespaceUri() const
Returns the attribute&#39;s resolved namespaceUri, or an empty string reference if the attribute does not...
Definition: qxmlstream.h:148