1 /****************************************************************************
3 ** Copyright (C) 2008 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 "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.
65 The QXmlSchemaValidator class loads, parses an XML instance document and validates it
66 against a W3C XML Schema that has been compiled with \l{QXmlSchema}.
68 The following example shows how to load a XML Schema from a local
69 file, check whether it is a valid schema document and use it for validation
70 of an XML instance document:
72 \snippet doc/src/snippets/qxmlschemavalidator/main.cpp 3
74 \section1 XML Schema Version
76 This class implements schema validation according to the \l{XML Schema} 1.0
79 \sa QXmlSchema, {xmlpatterns/schema}{XML Schema Validation Example}
83 Constructs a schema validator.
84 The schema used for validation must be referenced in the XML instance document
85 via the \c xsi:schemaLocation or \c xsi:noNamespaceSchemaLocation attribute.
87 QXmlSchemaValidator::QXmlSchemaValidator()
88 : d(new QXmlSchemaValidatorPrivate(QXmlSchema()))
93 Constructs a schema validator that will use \a schema for validation.
94 If an empty \l {QXmlSchema} schema is passed to the validator, the schema used
95 for validation must be referenced in the XML instance document
96 via the \c xsi:schemaLocation or \c xsi:noNamespaceSchemaLocation attribute.
98 QXmlSchemaValidator::QXmlSchemaValidator(const QXmlSchema &schema)
99 : d(new QXmlSchemaValidatorPrivate(schema))
104 Destroys this QXmlSchemaValidator.
106 QXmlSchemaValidator::~QXmlSchemaValidator()
112 Sets the \a schema that shall be used for further validation.
113 If the schema is empty, the schema used for validation must be referenced
114 in the XML instance document via the \c xsi:schemaLocation or
115 \c xsi:noNamespaceSchemaLocation attribute.
117 void QXmlSchemaValidator::setSchema(const QXmlSchema &schema)
119 d->setSchema(schema);
123 Validates the XML instance document read from \a data with the
124 given \a documentUri against the schema.
126 Returns \c true if the XML instance document is valid according to the
127 schema, \c false otherwise.
131 \snippet doc/src/snippets/qxmlschemavalidator/main.cpp 2
133 bool QXmlSchemaValidator::validate(const QByteArray &data, const QUrl &documentUri) const
135 QByteArray localData(data);
137 QBuffer buffer(&localData);
138 buffer.open(QIODevice::ReadOnly);
140 return validate(&buffer, documentUri);
144 Validates the XML instance document read from \a source against the schema.
146 Returns \c true if the XML instance document is valid according to the
147 schema, \c false otherwise.
151 \snippet doc/src/snippets/qxmlschemavalidator/main.cpp 0
153 bool QXmlSchemaValidator::validate(const QUrl &source) const
155 d->m_context->setMessageHandler(messageHandler());
156 d->m_context->setUriResolver(uriResolver());
157 d->m_context->setNetworkAccessManager(networkAccessManager());
159 const QPatternist::AutoPtr<QNetworkReply> reply(QPatternist::AccelTreeResourceLoader::load(source, d->m_context->networkAccessManager(),
160 d->m_context, QPatternist::AccelTreeResourceLoader::ContinueOnError));
162 return validate(reply.data(), source);
168 Validates the XML instance document read from \a source with the
169 given \a documentUri against the schema.
171 Returns \c true if the XML instance document is valid according to the
172 schema, \c false otherwise.
176 \snippet doc/src/snippets/qxmlschemavalidator/main.cpp 1
178 bool QXmlSchemaValidator::validate(QIODevice *source, const QUrl &documentUri) const
181 qWarning("A null QIODevice pointer cannot be passed.");
185 if (!source->isReadable()) {
186 qWarning("The device must be readable.");
190 const QUrl normalizedUri = QPatternist::XPathHelper::normalizeQueryURI(documentUri);
192 d->m_context->setMessageHandler(messageHandler());
193 d->m_context->setUriResolver(uriResolver());
194 d->m_context->setNetworkAccessManager(networkAccessManager());
196 QPatternist::NetworkAccessDelegator::Ptr delegator(new QPatternist::NetworkAccessDelegator(d->m_context->networkAccessManager(),
197 d->m_context->networkAccessManager()));
199 QPatternist::AccelTreeResourceLoader loader(d->m_context->namePool(), delegator, QPatternist::AccelTreeBuilder<true>::SourceLocationsFeature);
201 QPatternist::Item item;
203 item = loader.openDocument(source, normalizedUri, d->m_context);
204 } catch (QPatternist::Exception) {
208 const QAbstractXmlNodeModel *model = item.asNode().model();
210 QPatternist::XsdValidatedXmlNodeModel *validatedModel = new QPatternist::XsdValidatedXmlNodeModel(model);
212 QPatternist::XsdValidatingInstanceReader reader(validatedModel, normalizedUri, d->m_context);
214 reader.addSchema(d->m_schema, d->m_schemaDocumentUri);
217 } catch (QPatternist::Exception) {
225 Returns the name pool used by this QXmlSchemaValidator for constructing \l
226 {QXmlName} {names}. There is no setter for the name pool, because
227 mixing name pools causes errors due to name confusion.
229 QXmlNamePool QXmlSchemaValidator::namePool() const
231 return d->m_namePool;
235 Returns the schema that is used for validation.
237 QXmlSchema QXmlSchemaValidator::schema() const
239 return d->m_originalSchema;
243 Changes the \l {QAbstractMessageHandler}{message handler} for this
244 QXmlSchemaValidator to \a handler. The schema validator sends all parsing and
245 validation messages to this message handler. QXmlSchemaValidator does not take
246 ownership of \a handler.
248 Normally, the default message handler is sufficient. It writes
249 compile and validation messages to \e stderr. The default message
250 handler includes color codes if \e stderr can render colors.
252 When QXmlSchemaValidator calls QAbstractMessageHandler::message(),
253 the arguments are as follows:
257 \o message() argument
261 \o Only QtWarningMsg and QtFatalMsg are used. The former
262 identifies a warning, while the latter identifies an error.
264 \o const QString & description
265 \o An XHTML document which is the actual message. It is translated
266 into the current language.
268 \o const QUrl &identifier
269 \o Identifies the error with a URI, where the fragment is
270 the error code, and the rest of the URI is the error namespace.
272 \o const QSourceLocation & sourceLocation
273 \o Identifies where the error occurred.
277 void QXmlSchemaValidator::setMessageHandler(QAbstractMessageHandler *handler)
279 d->m_userMessageHandler = handler;
283 Returns the message handler that handles parsing and validation
284 messages for this QXmlSchemaValidator.
286 QAbstractMessageHandler *QXmlSchemaValidator::messageHandler() const
288 if (d->m_userMessageHandler)
289 return d->m_userMessageHandler;
291 return d->m_messageHandler.data()->value;
295 Sets the URI resolver to \a resolver. QXmlSchemaValidator does not take
296 ownership of \a resolver.
300 void QXmlSchemaValidator::setUriResolver(const QAbstractUriResolver *resolver)
302 d->m_uriResolver = resolver;
306 Returns the schema's URI resolver. If no URI resolver has been set,
307 QtXmlPatterns will use the URIs in instance documents as they are.
309 The URI resolver provides a level of abstraction, or \e{polymorphic
310 URIs}. A resolver can rewrite \e{logical} URIs to physical ones, or
311 it can translate obsolete or invalid URIs to valid ones.
313 When QtXmlPatterns calls QAbstractUriResolver::resolve() the
314 absolute URI is the URI mandated by the schema specification, and the
315 relative URI is the URI specified by the user.
319 const QAbstractUriResolver *QXmlSchemaValidator::uriResolver() const
321 return d->m_uriResolver;
325 Sets the network manager to \a manager.
326 QXmlSchemaValidator does not take ownership of \a manager.
328 \sa networkAccessManager()
330 void QXmlSchemaValidator::setNetworkAccessManager(QNetworkAccessManager *manager)
332 d->m_userNetworkAccessManager = manager;
336 Returns the network manager, or 0 if it has not been set.
338 \sa setNetworkAccessManager()
340 QNetworkAccessManager *QXmlSchemaValidator::networkAccessManager() const
342 if (d->m_userNetworkAccessManager)
343 return d->m_userNetworkAccessManager;
345 return d->m_networkAccessManager.data()->value;