XML Schema Validation Example▲
Sélectionnez
/**
**************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
***************************************************************************
*/
#include <QtGui>
#include <QtXmlPatterns>
#include
"mainwindow.h"
#include
"xmlsyntaxhighlighter.h"
class
MessageHandler : public
QAbstractMessageHandler
{
public
:
MessageHandler()
:
QAbstractMessageHandler(0
)
{
}
QString statusMessage() const
{
return
m_description;
}
int
line() const
{
return
m_sourceLocation.line();
}
int
column() const
{
return
m_sourceLocation.column();
}
protected
:
virtual
void
handleMessage(QtMsgType type, const
QString &
amp;description,
const
QUrl &
amp;identifier, const
QSourceLocation &
amp;sourceLocation)
{
Q_UNUSED(type);
Q_UNUSED(identifier);
m_description =
description;
m_sourceLocation =
sourceLocation;
}
private
:
QString m_description;
QSourceLocation m_sourceLocation;
}
;
MainWindow::
MainWindow()
{
setupUi(this
);
new
XmlSyntaxHighlighter(schemaView-&
gt;document());
new
XmlSyntaxHighlighter(instanceEdit-&
gt;document());
schemaSelection-&
gt;addItem(tr("Contact Schema"
));
schemaSelection-&
gt;addItem(tr("Recipe Schema"
));
schemaSelection-&
gt;addItem(tr("Order Schema"
));
instanceSelection-&
gt;addItem(tr("Valid Contact Instance"
));
instanceSelection-&
gt;addItem(tr("Invalid Contact Instance"
));
connect(schemaSelection, SIGNAL(currentIndexChanged(int
)), SLOT(schemaSelected(int
)));
connect(instanceSelection, SIGNAL(currentIndexChanged(int
)), SLOT(instanceSelected(int
)));
connect(validateButton, SIGNAL(clicked()), SLOT(validate()));
connect(instanceEdit, SIGNAL(textChanged()), SLOT(textChanged()));
validationStatus-&
gt;setAlignment(Qt::
AlignCenter |
Qt::
AlignVCenter);
schemaSelected(0
);
instanceSelected(0
);
}
void
MainWindow::
schemaSelected(int
index)
{
instanceSelection-&
gt;clear();
if
(index ==
0
) {
instanceSelection-&
gt;addItem(tr("Valid Contact Instance"
));
instanceSelection-&
gt;addItem(tr("Invalid Contact Instance"
));
}
else
if
(index ==
1
) {
instanceSelection-&
gt;addItem(tr("Valid Recipe Instance"
));
instanceSelection-&
gt;addItem(tr("Invalid Recipe Instance"
));
}
else
if
(index ==
2
) {
instanceSelection-&
gt;addItem(tr("Valid Order Instance"
));
instanceSelection-&
gt;addItem(tr("Invalid Order Instance"
));
}
textChanged();
const
QString fileName =
QStringLiteral(":/schema_"
)
+
QString::
number(index) +
QStringLiteral(".xsd"
);
QFile schemaFile(fileName);
if
(!
schemaFile.open(QIODevice::
ReadOnly)) {
qWarning() &
lt;&
lt; "Cannot open"
&
lt;&
lt; QDir::
toNativeSeparators(fileName)
&
lt;&
lt; ':'
&
lt;&
lt; schemaFile.errorString();
return
;
}
const
QString schemaText(QString::
fromUtf8(schemaFile.readAll()));
schemaView-&
gt;setPlainText(schemaText);
validate();
}
void
MainWindow::
instanceSelected(int
index)
{
if
(index &
lt; 0
) {
instanceEdit-&
gt;setPlainText(QString());
return
;
}
const
QString fileName =
QStringLiteral(":/instance_"
)
+
QString::
number(2
*
schemaSelection-&
gt;currentIndex() +
index)
+
QStringLiteral(".xml"
);
QFile instanceFile(fileName);
if
(!
instanceFile.open(QIODevice::
ReadOnly)) {
qWarning() &
lt;&
lt; "Cannot open"
&
lt;&
lt; QDir::
toNativeSeparators(fileName)
&
lt;&
lt; ':'
&
lt;&
lt; instanceFile.errorString();
return
;
}
const
QString instanceText(QString::
fromUtf8(instanceFile.readAll()));
instanceEdit-&
gt;setPlainText(instanceText);
validate();
}
void
MainWindow::
validate()
{
const
QByteArray schemaData =
schemaView-&
gt;toPlainText().toUtf8();
const
QByteArray instanceData =
instanceEdit-&
gt;toPlainText().toUtf8();
MessageHandler messageHandler;
QXmlSchema schema;
schema.setMessageHandler(&
amp;messageHandler);
schema.load(schemaData);
bool
errorOccurred =
false
;
if
(!
schema.isValid()) {
errorOccurred =
true
;
}
else
{
QXmlSchemaValidator validator(schema);
if
(!
validator.validate(instanceData))
errorOccurred =
true
;
}
if
(errorOccurred) {
validationStatus-&
gt;setText(messageHandler.statusMessage());
moveCursor(messageHandler.line(), messageHandler.column());
}
else
{
validationStatus-&
gt;setText(tr("validation successful"
));
}
const
QString styleSheet =
QString("QLabel {background: %1; padding: 3px}"
)
.arg(errorOccurred ? QColor(Qt::
red).lighter(160
).name() :
QColor(Qt::
green).lighter(160
).name());
validationStatus-&
gt;setStyleSheet(styleSheet);
}
void
MainWindow::
textChanged()
{
instanceEdit-&
gt;setExtraSelections(QList&
lt;QTextEdit::
ExtraSelection&
gt;());
}
void
MainWindow::
moveCursor(int
line, int
column)
{
instanceEdit-&
gt;moveCursor(QTextCursor::
Start);
for
(int
i =
1
; i &
lt; line; ++
i)
instanceEdit-&
gt;moveCursor(QTextCursor::
Down);
for
(int
i =
1
; i &
lt; column; ++
i)
instanceEdit-&
gt;moveCursor(QTextCursor::
Right);
QList&
lt;QTextEdit::
ExtraSelection&
gt; extraSelections;
QTextEdit::
ExtraSelection selection;
const
QColor lineColor =
QColor(Qt::
red).lighter(160
);
selection.format.setBackground(lineColor);
selection.format.setProperty(QTextFormat::
FullWidthSelection, true
);
selection.cursor =
instanceEdit-&
gt;textCursor();
selection.cursor.clearSelection();
extraSelections.append(selection);
instanceEdit-&
gt;setExtraSelections(extraSelections);
instanceEdit-&
gt;setFocus();
}