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 ****************************************************************************/
42 #include "qxmlschemavalidator.h"
43 #include "qxmlschemavalidator_p.h"
45 #include "qacceltreeresourceloader_p.h"
46 #include "qxmlschema.h"
47 #include "qxmlschema_p.h"
48 #include "qxsdvalidatinginstancereader_p.h"
50 #include <QtCore/QBuffer>
51 #include <QtCore/QIODevice>
52 #include <QtCore/QUrl>
57 \class QXmlSchemaValidator
59 \brief The QXmlSchemaValidator class validates XML instance documents against a W3C XML Schema.
64 \inmodule QtXmlPatterns
66 The QXmlSchemaValidator class loads, parses an XML instance document and validates it
67 against a W3C XML Schema that has been compiled with \l{QXmlSchema}.
69 The following example shows how to load a XML Schema from a local
70 file, check whether it is a valid schema document and use it for validation
71 of an XML instance document:
73 \snippet qxmlschemavalidator/main.cpp 3
75 \section1 XML Schema Version
77 This class implements schema validation according to the \l{XML Schema} 1.0
80 \sa QXmlSchema, {xmlpatterns/schema}{XML Schema Validation Example}
84 Constructs a schema validator.
85 The schema used for validation must be referenced in the XML instance document
86 via the \c xsi:schemaLocation or \c xsi:noNamespaceSchemaLocation attribute.
88 QXmlSchemaValidator::QXmlSchemaValidator()
89 : d(new QXmlSchemaValidatorPrivate(QXmlSchema()))
94 Constructs a schema validator that will use \a schema for validation.
95 If an empty \l {QXmlSchema} schema is passed to the validator, the schema used
96 for validation must be referenced in the XML instance document
97 via the \c xsi:schemaLocation or \c xsi:noNamespaceSchemaLocation attribute.
99 QXmlSchemaValidator::QXmlSchemaValidator(const QXmlSchema &schema)
100 : d(new QXmlSchemaValidatorPrivate(schema))
105 Destroys this QXmlSchemaValidator.
107 QXmlSchemaValidator::~QXmlSchemaValidator()
113 Sets the \a schema that shall be used for further validation.
114 If the schema is empty, the schema used for validation must be referenced
115 in the XML instance document via the \c xsi:schemaLocation or
116 \c xsi:noNamespaceSchemaLocation attribute.
118 void QXmlSchemaValidator::setSchema(const QXmlSchema &schema)
120 d->setSchema(schema);
124 Validates the XML instance document read from \a data with the
125 given \a documentUri against the schema.
127 Returns \c true if the XML instance document is valid according to the
128 schema, \c false otherwise.
132 \snippet qxmlschemavalidator/main.cpp 2
134 bool QXmlSchemaValidator::validate(const QByteArray &data, const QUrl &documentUri) const
136 QByteArray localData(data);
138 QBuffer buffer(&localData);
139 buffer.open(QIODevice::ReadOnly);
141 return validate(&buffer, documentUri);
145 Validates the XML instance document read from \a source against the schema.
147 Returns \c true if the XML instance document is valid according to the
148 schema, \c false otherwise.
152 \snippet qxmlschemavalidator/main.cpp 0
154 bool QXmlSchemaValidator::validate(const QUrl &source) const
156 d->m_context->setMessageHandler(messageHandler());
157 d->m_context->setUriResolver(uriResolver());
158 d->m_context->setNetworkAccessManager(networkAccessManager());
160 const QPatternist::AutoPtr<QNetworkReply> reply(QPatternist::AccelTreeResourceLoader::load(source, d->m_context->networkAccessManager(),
161 d->m_context, QPatternist::AccelTreeResourceLoader::ContinueOnError));
163 return validate(reply.data(), source);
169 Validates the XML instance document read from \a source with the
170 given \a documentUri against the schema.
172 Returns \c true if the XML instance document is valid according to the
173 schema, \c false otherwise.
177 \snippet qxmlschemavalidator/main.cpp 1
179 bool QXmlSchemaValidator::validate(QIODevice *source, const QUrl &documentUri) const
182 qWarning("A null QIODevice pointer cannot be passed.");
186 if (!source->isReadable()) {
187 qWarning("The device must be readable.");
191 const QUrl normalizedUri = QPatternist::XPathHelper::normalizeQueryURI(documentUri);
193 d->m_context->setMessageHandler(messageHandler());
194 d->m_context->setUriResolver(uriResolver());
195 d->m_context->setNetworkAccessManager(networkAccessManager());
197 QPatternist::NetworkAccessDelegator::Ptr delegator(new QPatternist::NetworkAccessDelegator(d->m_context->networkAccessManager(),
198 d->m_context->networkAccessManager()));
200 QPatternist::AccelTreeResourceLoader loader(d->m_context->namePool(), delegator, QPatternist::AccelTreeBuilder<true>::SourceLocationsFeature);
202 QPatternist::Item item;
204 item = loader.openDocument(source, normalizedUri, d->m_context);
205 } catch (QPatternist::Exception) {
209 const QAbstractXmlNodeModel *model = item.asNode().model();
211 QPatternist::XsdValidatedXmlNodeModel *validatedModel = new QPatternist::XsdValidatedXmlNodeModel(model);
213 QPatternist::XsdValidatingInstanceReader reader(validatedModel, normalizedUri, d->m_context);
215 reader.addSchema(d->m_schema, d->m_schemaDocumentUri);
218 } catch (QPatternist::Exception) {
226 Returns the name pool used by this QXmlSchemaValidator for constructing \l
227 {QXmlName} {names}. There is no setter for the name pool, because
228 mixing name pools causes errors due to name confusion.
230 QXmlNamePool QXmlSchemaValidator::namePool() const
232 return d->m_namePool;
236 Returns the schema that is used for validation.
238 QXmlSchema QXmlSchemaValidator::schema() const
240 return d->m_originalSchema;
244 Changes the \l {QAbstractMessageHandler}{message handler} for this
245 QXmlSchemaValidator to \a handler. The schema validator sends all parsing and
246 validation messages to this message handler. QXmlSchemaValidator does not take
247 ownership of \a handler.
249 Normally, the default message handler is sufficient. It writes
250 compile and validation messages to \e stderr. The default message
251 handler includes color codes if \e stderr can render colors.
253 When QXmlSchemaValidator calls QAbstractMessageHandler::message(),
254 the arguments are as follows:
258 \li message() argument
262 \li Only QtWarningMsg and QtFatalMsg are used. The former
263 identifies a warning, while the latter identifies an error.
265 \li const QString & description
266 \li An XHTML document which is the actual message. It is translated
267 into the current language.
269 \li const QUrl &identifier
270 \li Identifies the error with a URI, where the fragment is
271 the error code, and the rest of the URI is the error namespace.
273 \li const QSourceLocation & sourceLocation
274 \li Identifies where the error occurred.
278 void QXmlSchemaValidator::setMessageHandler(QAbstractMessageHandler *handler)
280 d->m_userMessageHandler = handler;
284 Returns the message handler that handles parsing and validation
285 messages for this QXmlSchemaValidator.
287 QAbstractMessageHandler *QXmlSchemaValidator::messageHandler() const
289 if (d->m_userMessageHandler)
290 return d->m_userMessageHandler;
292 return d->m_messageHandler.data()->value;
296 Sets the URI resolver to \a resolver. QXmlSchemaValidator does not take
297 ownership of \a resolver.
301 void QXmlSchemaValidator::setUriResolver(const QAbstractUriResolver *resolver)
303 d->m_uriResolver = resolver;
307 Returns the schema's URI resolver. If no URI resolver has been set,
308 Qt XML Patterns will use the URIs in instance documents as they are.
310 The URI resolver provides a level of abstraction, or \e{polymorphic
311 URIs}. A resolver can rewrite \e{logical} URIs to physical ones, or
312 it can translate obsolete or invalid URIs to valid ones.
314 When Qt XML Patterns calls QAbstractUriResolver::resolve() the
315 absolute URI is the URI mandated by the schema specification, and the
316 relative URI is the URI specified by the user.
320 const QAbstractUriResolver *QXmlSchemaValidator::uriResolver() const
322 return d->m_uriResolver;
326 Sets the network manager to \a manager.
327 QXmlSchemaValidator does not take ownership of \a manager.
329 \sa networkAccessManager()
331 void QXmlSchemaValidator::setNetworkAccessManager(QNetworkAccessManager *manager)
333 d->m_userNetworkAccessManager = manager;
337 Returns the network manager, or 0 if it has not been set.
339 \sa setNetworkAccessManager()
341 QNetworkAccessManager *QXmlSchemaValidator::networkAccessManager() const
343 if (d->m_userNetworkAccessManager)
344 return d->m_userNetworkAccessManager;
346 return d->m_networkAccessManager.data()->value;