summaryrefslogtreecommitdiff
path: root/src/xmlpatterns/api
diff options
context:
space:
mode:
authorTobias Koenig <tokoe@kde.org>2009-05-16 12:19:10 +0200
committerTobias Koenig <tokoe@kde.org>2009-05-16 12:19:10 +0200
commit135a028d9dc9a28a0a072665a7dc43b7e9e187be (patch)
treed259e1d265589d10a541899d4982ab4e656900eb /src/xmlpatterns/api
parent210bd7b6033e41aad61fe131002dc5e496d7427a (diff)
downloadqt4-tools-135a028d9dc9a28a0a072665a7dc43b7e9e187be.tar.gz
Add W3C XML Schema validation support
This was done by Tobias Koenig, as part of an internship at Trolltech/Qt Software, started at Wed Oct 1 18:32:43 2008 +0200, and the last commit being part of this commit dating Tue Feb 24 11:03:36 2009 +0100. This is work consisting of about 650 commits squashed into one, where the first commit was 61b280386c1905a15690fdd917dcbc8eb09b6283, in the repository before Qt's history cut.
Diffstat (limited to 'src/xmlpatterns/api')
-rw-r--r--src/xmlpatterns/api/api.pri11
-rw-r--r--src/xmlpatterns/api/qabstractxmlnodemodel.cpp16
-rw-r--r--src/xmlpatterns/api/qabstractxmlnodemodel.h5
-rw-r--r--src/xmlpatterns/api/qabstractxmlnodemodel_p.h10
-rw-r--r--src/xmlpatterns/api/qabstractxmlpullprovider.cpp147
-rw-r--r--src/xmlpatterns/api/qabstractxmlpullprovider_p.h83
-rw-r--r--src/xmlpatterns/api/qpullbridge.cpp202
-rw-r--r--src/xmlpatterns/api/qpullbridge_p.h73
-rw-r--r--src/xmlpatterns/api/qresourcedelegator.cpp8
-rw-r--r--src/xmlpatterns/api/qxmlnamepool.cpp4
-rw-r--r--src/xmlpatterns/api/qxmlnamepool.h7
-rw-r--r--src/xmlpatterns/api/qxmlquery.cpp12
-rw-r--r--src/xmlpatterns/api/qxmlquery.h11
-rw-r--r--src/xmlpatterns/api/qxmlquery_p.h24
-rw-r--r--src/xmlpatterns/api/qxmlschema.cpp229
-rw-r--r--src/xmlpatterns/api/qxmlschema.h66
-rw-r--r--src/xmlpatterns/api/qxmlschema_p.cpp169
-rw-r--r--src/xmlpatterns/api/qxmlschema_p.h79
-rw-r--r--src/xmlpatterns/api/qxmlschemavalidator.cpp264
-rw-r--r--src/xmlpatterns/api/qxmlschemavalidator.h64
-rw-r--r--src/xmlpatterns/api/qxmlschemavalidator_p.h98
21 files changed, 1566 insertions, 16 deletions
diff --git a/src/xmlpatterns/api/api.pri b/src/xmlpatterns/api/api.pri
index a0298f25fb..9fcc2f53e6 100644
--- a/src/xmlpatterns/api/api.pri
+++ b/src/xmlpatterns/api/api.pri
@@ -3,11 +3,13 @@ HEADERS += $$PWD/qabstractxmlforwarditerator_p.h \
$$PWD/qabstracturiresolver.h \
$$PWD/qabstractxmlnodemodel.h \
$$PWD/qabstractxmlnodemodel_p.h \
+ $$PWD/qabstractxmlpullprovider_p.h \
$$PWD/qabstractxmlreceiver.h \
$$PWD/qabstractxmlreceiver_p.h \
$$PWD/qdeviceresourceloader_p.h \
$$PWD/qiodevicedelegate_p.h \
$$PWD/qnetworkaccessdelegator_p.h \
+ $$PWD/qpullbridge_p.h \
$$PWD/qresourcedelegator_p.h \
$$PWD/qsimplexmlnodemodel.h \
$$PWD/qsourcelocation.h \
@@ -20,6 +22,10 @@ HEADERS += $$PWD/qabstractxmlforwarditerator_p.h \
$$PWD/qxmlquery_p.h \
$$PWD/qxmlresultitems.h \
$$PWD/qxmlresultitems_p.h \
+ $$PWD/qxmlschema.h \
+ $$PWD/qxmlschema_p.h \
+ $$PWD/qxmlschemavalidator.h \
+ $$PWD/qxmlschemavalidator_p.h \
$$PWD/qxmlserializer.h \
$$PWD/qxmlserializer_p.h \
$$PWD/../../../tools/xmlpatterns/qcoloringmessagehandler_p.h \
@@ -29,9 +35,11 @@ SOURCES += $$PWD/qvariableloader.cpp \
$$PWD/qabstractmessagehandler.cpp \
$$PWD/qabstracturiresolver.cpp \
$$PWD/qabstractxmlnodemodel.cpp \
+ $$PWD/qabstractxmlpullprovider.cpp \
$$PWD/qabstractxmlreceiver.cpp \
$$PWD/qiodevicedelegate.cpp \
$$PWD/qnetworkaccessdelegator.cpp \
+ $$PWD/qpullbridge.cpp \
$$PWD/qresourcedelegator.cpp \
$$PWD/qsimplexmlnodemodel.cpp \
$$PWD/qsourcelocation.cpp \
@@ -41,6 +49,9 @@ SOURCES += $$PWD/qvariableloader.cpp \
$$PWD/qxmlnamepool.cpp \
$$PWD/qxmlquery.cpp \
$$PWD/qxmlresultitems.cpp \
+ $$PWD/qxmlschema.cpp \
+ $$PWD/qxmlschema_p.cpp \
+ $$PWD/qxmlschemavalidator.cpp \
$$PWD/qxmlserializer.cpp \
$$PWD/../../../tools/xmlpatterns/qcoloringmessagehandler.cpp \
$$PWD/../../../tools/xmlpatterns/qcoloroutput.cpp
diff --git a/src/xmlpatterns/api/qabstractxmlnodemodel.cpp b/src/xmlpatterns/api/qabstractxmlnodemodel.cpp
index 0caa8c48f4..f535ec8a8e 100644
--- a/src/xmlpatterns/api/qabstractxmlnodemodel.cpp
+++ b/src/xmlpatterns/api/qabstractxmlnodemodel.cpp
@@ -1666,4 +1666,20 @@ void QAbstractXmlNodeModel::copyNodeTo(const QXmlNodeModelIndex &node,
"This function is not expected to be called.");
}
+/*!
+ Returns the source location for the object with the given \a index
+ or a default constructed QSourceLocation in case no location
+ information is available.
+
+ \since TODO
+ */
+QSourceLocation QAbstractXmlNodeModel::sourceLocation(const QXmlNodeModelIndex &index) const
+{
+ // TODO: make this method virtual in Qt5 to allow source location support in custom models
+ if (d_ptr)
+ return d_ptr->sourceLocation(index);
+ else
+ return QSourceLocation();
+}
+
QT_END_NAMESPACE
diff --git a/src/xmlpatterns/api/qabstractxmlnodemodel.h b/src/xmlpatterns/api/qabstractxmlnodemodel.h
index 6c9574c420..1d860a31dc 100644
--- a/src/xmlpatterns/api/qabstractxmlnodemodel.h
+++ b/src/xmlpatterns/api/qabstractxmlnodemodel.h
@@ -56,6 +56,7 @@ QT_MODULE(XmlPatterns)
class QAbstractXmlNodeModel;
class QAbstractXmlNodeModelPrivate;
class QAbstractXmlReceiver;
+class QSourceLocation;
class QUrl;
class QXmlName;
class QXmlNodeModelIndex;
@@ -69,6 +70,7 @@ namespace QPatternist
class DynamicContext;
class Item;
class ItemType;
+ class XsdValidatedXmlNodeModel;
template<typename TResult, typename TSource, typename TMapper, typename Context> class ItemMappingIterator;
template<typename TResult, typename TSource, typename TMapper> class SequenceMappingIterator;
typedef QExplicitlySharedDataPointer<ItemType> ItemTypePtr;
@@ -315,6 +317,8 @@ public:
QAbstractXmlReceiver *const receiver,
const NodeCopySettings &) const;
+ QSourceLocation sourceLocation(const QXmlNodeModelIndex &index) const;
+
protected:
virtual QXmlNodeModelIndex nextFromSimpleAxis(SimpleAxis axis, const QXmlNodeModelIndex &origin) const = 0;
@@ -343,6 +347,7 @@ protected:
private:
friend class QPatternist::ItemMappingIterator<QXmlNodeModelIndex, QXmlNodeModelIndex, const QAbstractXmlNodeModel *, QExplicitlySharedDataPointer<QPatternist::DynamicContext> >;
friend class QPatternist::SequenceMappingIterator<QXmlNodeModelIndex, QXmlNodeModelIndex, const QAbstractXmlNodeModel *>;
+ friend class QPatternist::XsdValidatedXmlNodeModel;
inline QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QXmlNodeModelIndex> > mapToSequence(const QXmlNodeModelIndex &ni,
const QExplicitlySharedDataPointer<QPatternist::DynamicContext> &) const;
diff --git a/src/xmlpatterns/api/qabstractxmlnodemodel_p.h b/src/xmlpatterns/api/qabstractxmlnodemodel_p.h
index 16ce6134a5..0ab1b26aeb 100644
--- a/src/xmlpatterns/api/qabstractxmlnodemodel_p.h
+++ b/src/xmlpatterns/api/qabstractxmlnodemodel_p.h
@@ -52,6 +52,9 @@
#ifndef QABSTRACTXMLNODEMODEL_P_H
#define QABSTRACTXMLNODEMODEL_P_H
+#include "qabstractxmlnodemodel.h"
+#include "qsourcelocation.h"
+
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
@@ -62,6 +65,13 @@ public:
virtual ~QAbstractXmlNodeModelPrivate()
{
}
+
+ virtual QSourceLocation sourceLocation(const QXmlNodeModelIndex &index) const
+ {
+ Q_UNUSED(index);
+
+ return QSourceLocation();
+ }
};
QT_END_NAMESPACE
diff --git a/src/xmlpatterns/api/qabstractxmlpullprovider.cpp b/src/xmlpatterns/api/qabstractxmlpullprovider.cpp
new file mode 100644
index 0000000000..a80604b509
--- /dev/null
+++ b/src/xmlpatterns/api/qabstractxmlpullprovider.cpp
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the $MODULE$ of the Qt Toolkit.
+**
+** $TROLLTECH_DUAL_LICENSE$
+**
+****************************************************************************/
+
+#include <QHash>
+
+#include "qxmlname.h"
+#include "qnamepool_p.h"
+#include "qabstractxmlpullprovider_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+// TODO have example where query selects, and the events for the result are indented
+
+/*!
+ \internal
+ \class AbstractXmlPullProvider
+ \brief The AbstractXmlPullProvider class provides a pull-based stream interface for the XPath Data Model.
+ \reentrant
+ \ingroup xml-tools
+
+ AbstractXmlPullProvider allows a stream of items from the XPath Data Model -- essentially XML --
+ to be iterated over. The subclass of AbstractXmlPullProvider provides the events, and the
+ user calling next() and so on, consumes them. AbstractXmlPullProvider can be considered
+ a forward-only, non-reversible iterator.
+
+ Note that the content the events describes, are not necessarily a well-formed XML document, but
+ rather an instance of the XPath Data model, to be specific. For instance, maybe a pull provider
+ returns two atomic values, followed by an element tree, and at the end two document nodes.
+
+ If you are subclassing AbstractXmlPullProvider, be careful to correctly implement
+ the behaviors, as described for the individual members and events.
+
+ \sa AbstractXmlPullProvider::Event
+ */
+
+/*!
+ \enum AbstractXmlPullProvider::Event
+ \value StartOfInput The value AbstractXmlPullProvider::current() returns before the first call to next().
+ \value AtomicValue an atomic value such as an \c xs:integer, \c xs:hexBinary, or \c xs:dateTime. Atomic values
+ can only be top level items.
+ \value StartDocument Signals the start of a document node. Note that a AbstractXmlPullProvider can provide
+ a sequence of document nodes.
+ \value EndDocument Signals the end of a document node. StartDocument and EndDocument are always balanced
+ and always top-level events. For instance, StartDocument can never appear after any StartElement
+ events that hasn't been balanced by the corresponding amount of EndElement events.
+ \value StartElement Signals an element start tag.
+ \value EndElement Signals the end of an element. StartElement and EndElement events are always balanced.
+ \value Text Signals a text node. Adjacent text nodes cannot occur.
+ \value ProcessingInstruction A processing instruction. Its name is returned from name(), and its value in stringValue().
+ \value Comment a comment node. Its value can be retrieved with stingValue().
+ \value Attribute Signals an attribute node. Attribute events can only appear after Namespace events, or
+ if no such are sent, after the StartElement. In addition they must appear sequentially,
+ and each name must be unique. The ordering of attribute events is undefined and insignificant.
+ \value Namespace Signals a namespace binding. They occur very infrequently and are not needed for attributes
+ and elements. Namespace events can only appear after the StartElement event. The
+ ordering of namespace events is undefined and insignificant.
+ \value EndOfInput When next() is called after the last event, EndOfInput is returned.
+
+ \sa AbstractXmlPullProvider::current()
+ */
+
+/*!
+ Constucts a AbstractXmlPullProvider instance.
+ */
+AbstractXmlPullProvider::AbstractXmlPullProvider()
+{
+}
+
+/*!
+ Destructs this AbstractXmlPullProvider.
+ */
+AbstractXmlPullProvider::~AbstractXmlPullProvider()
+{
+}
+
+/*!
+ \fn Event AbstractXmlPullProvider::next() = 0;
+ Advances this AbstractXmlPullProvider, and returns the new event.
+
+ \sa current()
+ */
+
+/*!
+ \fn Event AbstractXmlPullProvider::current() const = 0;
+ Returns the event that next() returned the last time it was called. It doesn't
+ alter this AbstractXmlPullProvider.
+
+ current() may not modify this AbstractXmlPullProvider's state. Subsequent calls to current()
+ must return the same value.
+
+ \sa AbstractXmlPullProvider::Event
+ */
+
+/*!
+ \fn QName AbstractXmlPullProvider::name() const = 0;
+ If the current event is StartElement,
+ EndElement, ProcessingInstruction, Attribute, or Namespace, the node's name is returned.
+
+ If the current event is ProcessingInstruction,
+ the processing instruction target is in in the local name.
+
+ If the current event is Namespace, the name's namespace URI is the namespace, and
+ the local name is the prefix the name is binding to.
+
+ In all other cases, an invalid QName is returned.
+ */
+
+/*!
+ \fn QVariant AbstractXmlPullProvider::atomicValue() const = 0;
+
+ If current() event is AtomicValue, the atomic value is returned as a QVariant.
+ In all other cases, this function returns a null QVariant.
+ */
+
+/*!
+ \fn QString AbstractXmlPullProvider::stringValue() const = 0;
+
+ If current() is Text, the text node's value is returned.
+
+ If the current() event is Comment, its value is returned. The subclasser guarantees
+ it does not contain the string "-->".
+
+ If the current() event is ProcessingInstruction, its data is returned. The subclasser
+ guarantees the data does not contain the string "?>".
+
+ In other cases, it returns a default constructed string.
+ */
+
+/*!
+ \fn QHash<QXmlName, QString> AbstractXmlPullProvider::attributes() = 0;
+
+ If the current() is Element, the attributes of the element are returned,
+ an empty list of attributes otherwise.
+ */
+
+QT_END_NAMESPACE
+
diff --git a/src/xmlpatterns/api/qabstractxmlpullprovider_p.h b/src/xmlpatterns/api/qabstractxmlpullprovider_p.h
new file mode 100644
index 0000000000..d05e6496a3
--- /dev/null
+++ b/src/xmlpatterns/api/qabstractxmlpullprovider_p.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the $MODULE$ of the Qt Toolkit.
+**
+** $TROLLTECH_DUAL_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef QABSTRACTXMLPULLPROVIDER_H
+#define QABSTRACTXMLPULLPROVIDER_H
+
+#include <QtCore/QtGlobal>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QXmlItem;
+class QXmlName;
+class QString;
+class QVariant;
+template<typename Key, typename Value> class QHash;
+
+namespace QPatternist
+{
+ class AbstractXmlPullProviderPrivate;
+
+ class AbstractXmlPullProvider
+ {
+ public:
+ AbstractXmlPullProvider();
+ virtual ~AbstractXmlPullProvider();
+
+ enum Event
+ {
+ StartOfInput = 1,
+ AtomicValue = 1 << 1,
+ StartDocument = 1 << 2,
+ EndDocument = 1 << 3,
+ StartElement = 1 << 4,
+ EndElement = 1 << 5,
+ Text = 1 << 6,
+ ProcessingInstruction = 1 << 7,
+ Comment = 1 << 8,
+ Attribute = 1 << 9,
+ Namespace = 1 << 10,
+ EndOfInput = 1 << 11
+ };
+
+ virtual Event next() = 0;
+ virtual Event current() const = 0;
+ virtual QXmlName name() const = 0;
+ virtual QVariant atomicValue() const = 0;
+ virtual QString stringValue() const = 0;
+
+ virtual QHash<QXmlName, QString> attributes() = 0;
+ virtual QHash<QXmlName, QXmlItem> attributeItems() = 0;
+
+ /* *** The functions below are internal. */
+ private:
+ Q_DISABLE_COPY(AbstractXmlPullProvider)
+ AbstractXmlPullProviderPrivate *d;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qpullbridge.cpp b/src/xmlpatterns/api/qpullbridge.cpp
new file mode 100644
index 0000000000..f34733937c
--- /dev/null
+++ b/src/xmlpatterns/api/qpullbridge.cpp
@@ -0,0 +1,202 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the $MODULE$ of the Qt Toolkit.
+**
+** $TROLLTECH_DUAL_LICENSE$
+**
+****************************************************************************/
+
+#include <QVariant>
+
+#include "qabstractxmlnodemodel_p.h"
+#include "qitemmappingiterator_p.h"
+#include "qitem_p.h"
+#include "qxmlname.h"
+#include "qxmlquery_p.h"
+
+#include "qpullbridge_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+/*!
+ \brief Bridges a QPatternist::SequenceIterator to QAbstractXmlPullProvider.
+ \class QPatternist::PullBridge
+ \internal
+ \reentrant
+ \ingroup xml-tools
+
+ The approach of this class is rather straight forward since QPatternist::SequenceIterator
+ and QAbstractXmlPullProvider are conceptually similar. While QPatternist::SequenceIterator only
+ delivers top level items(since it's not an event stream, it's a list of items), PullBridge
+ needs to recursively iterate the children of nodes too, which is achieved through the
+ stack m_iterators.
+ */
+
+AbstractXmlPullProvider::Event PullBridge::next()
+{
+ m_index = m_iterators.top().second->next();
+
+ if(!m_index.isNull())
+ {
+ Item item(m_index);
+
+ if(item && item.isAtomicValue())
+ m_current = AtomicValue;
+ else
+ {
+ Q_ASSERT(item.isNode());
+
+ switch(m_index.kind())
+ {
+ case QXmlNodeModelIndex::Attribute:
+ {
+ m_current = Attribute;
+ break;
+ }
+ case QXmlNodeModelIndex::Comment:
+ {
+ m_current = Comment;
+ break;
+ }
+ case QXmlNodeModelIndex::Element:
+ {
+ m_iterators.push(qMakePair(StartElement, m_index.iterate(QXmlNodeModelIndex::AxisChild)));
+ m_current = StartElement;
+ break;
+ }
+ case QXmlNodeModelIndex::Document:
+ {
+ m_iterators.push(qMakePair(StartDocument, m_index.iterate(QXmlNodeModelIndex::AxisChild)));
+ m_current = StartDocument;
+ break;
+ }
+ case QXmlNodeModelIndex::Namespace:
+ {
+ m_current = Namespace;
+ break;
+ }
+ case QXmlNodeModelIndex::ProcessingInstruction:
+ {
+ m_current = ProcessingInstruction;
+ break;
+ }
+ case QXmlNodeModelIndex::Text:
+ {
+ m_current = Text;
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ if(m_iterators.isEmpty())
+ m_current = EndOfInput;
+ else
+ {
+ switch(m_iterators.top().first)
+ {
+ case StartOfInput:
+ {
+ m_current = EndOfInput;
+ break;
+ }
+ case StartElement:
+ {
+ m_current = EndElement;
+ m_iterators.pop();
+ break;
+ }
+ case StartDocument:
+ {
+ m_current = EndDocument;
+ m_iterators.pop();
+ break;
+ }
+ default:
+ {
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "Invalid value.");
+ m_current = EndOfInput;
+ }
+ }
+ }
+
+ }
+
+ return m_current;
+}
+
+AbstractXmlPullProvider::Event PullBridge::current() const
+{
+ return m_current;
+}
+
+QXmlNodeModelIndex PullBridge::index() const
+{
+ return m_index;
+}
+
+QSourceLocation PullBridge::sourceLocation() const
+{
+ return m_index.model()->sourceLocation(m_index);
+}
+
+QXmlName PullBridge::name() const
+{
+ return m_index.name();
+}
+
+QVariant PullBridge::atomicValue() const
+{
+ return QVariant();
+}
+
+QString PullBridge::stringValue() const
+{
+ return QString();
+}
+
+QHash<QXmlName, QString> PullBridge::attributes()
+{
+ Q_ASSERT(m_current == StartElement);
+
+ QHash<QXmlName, QString> attributes;
+
+ QXmlNodeModelIndex::Iterator::Ptr it = m_index.iterate(QXmlNodeModelIndex::AxisAttribute);
+ QXmlNodeModelIndex index = it->next();
+ while (!index.isNull()) {
+ const Item attribute(index);
+ attributes.insert(index.name(), index.stringValue());
+
+ index = it->next();
+ }
+
+ return attributes;
+}
+
+QHash<QXmlName, QXmlItem> PullBridge::attributeItems()
+{
+ Q_ASSERT(m_current == StartElement);
+
+ QHash<QXmlName, QXmlItem> attributes;
+
+ QXmlNodeModelIndex::Iterator::Ptr it = m_index.iterate(QXmlNodeModelIndex::AxisAttribute);
+ QXmlNodeModelIndex index = it->next();
+ while (!index.isNull()) {
+ const Item attribute(index);
+ attributes.insert(index.name(), QXmlItem(index));
+
+ index = it->next();
+ }
+
+ return attributes;
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/xmlpatterns/api/qpullbridge_p.h b/src/xmlpatterns/api/qpullbridge_p.h
new file mode 100644
index 0000000000..823d27bfc3
--- /dev/null
+++ b/src/xmlpatterns/api/qpullbridge_p.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the $MODULE$ of the Qt Toolkit.
+**
+** $TROLLTECH_DUAL_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef PATTERNIST_PULLBRIDGE_P_H
+#define PATTERNIST_PULLBRIDGE_P_H
+
+#include <QtCore/QPair>
+#include <QtCore/QStack>
+
+#include "qabstractxmlforwarditerator_p.h"
+#include "qabstractxmlpullprovider_p.h"
+#include "qitem_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ class PullBridge : public AbstractXmlPullProvider
+ {
+ public:
+ inline PullBridge(const QXmlNodeModelIndex::Iterator::Ptr &it) : m_current(StartOfInput)
+ {
+ Q_ASSERT(it);
+ m_iterators.push(qMakePair(StartOfInput, it));
+ }
+
+ virtual Event next();
+ virtual Event current() const;
+ virtual QXmlName name() const;
+ /**
+ * Returns always an empty QVariant.
+ */
+ virtual QVariant atomicValue() const;
+ virtual QString stringValue() const;
+ virtual QHash<QXmlName, QString> attributes();
+ virtual QHash<QXmlName, QXmlItem> attributeItems();
+
+ QXmlNodeModelIndex index() const;
+ QSourceLocation sourceLocation() const;
+
+ private:
+ typedef QStack<QPair<Event, QXmlNodeModelIndex::Iterator::Ptr> > IteratorStack;
+ IteratorStack m_iterators;
+ QXmlNodeModelIndex m_index;
+ Event m_current;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qresourcedelegator.cpp b/src/xmlpatterns/api/qresourcedelegator.cpp
index 9d43419310..fceef30918 100644
--- a/src/xmlpatterns/api/qresourcedelegator.cpp
+++ b/src/xmlpatterns/api/qresourcedelegator.cpp
@@ -45,14 +45,6 @@ QT_BEGIN_NAMESPACE
using namespace QPatternist;
-/**
- * Duplicated in qacceltreeresourceloader.cpp.
- */
-static inline uint qHash(const QUrl &uri)
-{
- return qHash(uri.toString());
-}
-
bool ResourceDelegator::isUnparsedTextAvailable(const QUrl &uri,
const QString &encoding)
{
diff --git a/src/xmlpatterns/api/qxmlnamepool.cpp b/src/xmlpatterns/api/qxmlnamepool.cpp
index 2337f8d813..11274abf02 100644
--- a/src/xmlpatterns/api/qxmlnamepool.cpp
+++ b/src/xmlpatterns/api/qxmlnamepool.cpp
@@ -96,6 +96,10 @@ QXmlNamePool::~QXmlNamePool()
{
}
+QXmlNamePool::QXmlNamePool(QPatternist::NamePool *namePool) : d(QExplicitlySharedDataPointer<QPatternist::NamePool>(namePool))
+{
+}
+
/*!
Assigns the \a other name pool to this one.
*/
diff --git a/src/xmlpatterns/api/qxmlnamepool.h b/src/xmlpatterns/api/qxmlnamepool.h
index 3c1e112114..87856ee5b3 100644
--- a/src/xmlpatterns/api/qxmlnamepool.h
+++ b/src/xmlpatterns/api/qxmlnamepool.h
@@ -54,6 +54,8 @@ QT_MODULE(XmlPatterns)
namespace QPatternist
{
class NamePool;
+ class XsdSchemaParser;
+ class XsdValidatingInstanceReader;
}
namespace QPatternistSDK
@@ -73,10 +75,15 @@ public:
QXmlNamePool &operator=(const QXmlNamePool &other);
private:
+ QXmlNamePool(QPatternist::NamePool *namePool);
friend class QXmlQueryPrivate;
friend class QXmlQuery;
+ friend class QXmlSchemaPrivate;
+ friend class QXmlSchemaValidatorPrivate;
friend class QXmlSerializerPrivate;
friend class QXmlName;
+ friend class QPatternist::XsdSchemaParser;
+ friend class QPatternist::XsdValidatingInstanceReader;
friend class QPatternistSDK::Global;
QExplicitlySharedDataPointer<QPatternist::NamePool> d;
};
diff --git a/src/xmlpatterns/api/qxmlquery.cpp b/src/xmlpatterns/api/qxmlquery.cpp
index 5f9d87d748..423da3e602 100644
--- a/src/xmlpatterns/api/qxmlquery.cpp
+++ b/src/xmlpatterns/api/qxmlquery.cpp
@@ -231,6 +231,18 @@ QT_BEGIN_NAMESPACE
\value XQuery10 XQuery 1.0.
\value XSLT20 XSLT 2.0
+ \omitvalue XmlSchema11IdentityConstraintSelector The selector, the restricted
+ XPath pattern found in W3C XML Schema 1.1 for uniqueness
+ contraints. Apart from restricting the syntax, the type check stage
+ for the expression assumes a sequence of nodes to be the focus.
+ \omitvalue XmlSchema11IdentityConstraintField The field, the restricted
+ XPath pattern found in W3C XML Schema 1.1 for uniqueness
+ contraints. Apart from restricting the syntax, the type check stage
+ for the expression assumes a sequence of nodes to be the focus.
+ \omitvalue XPath20 Signifies XPath 2.0. Has no effect in the public API, it's
+ used internally. As With XmlSchema11IdentityConstraintSelector and
+ XmlSchema11IdentityConstraintField, the type check stage
+ for the expression assumes a sequence of nodes to be the focus.
\sa setQuery()
*/
diff --git a/src/xmlpatterns/api/qxmlquery.h b/src/xmlpatterns/api/qxmlquery.h
index 138819c087..c9f949ee10 100644
--- a/src/xmlpatterns/api/qxmlquery.h
+++ b/src/xmlpatterns/api/qxmlquery.h
@@ -71,6 +71,8 @@ namespace QPatternistSDK
namespace QPatternist
{
+ class XsdSchemaParser;
+ class XsdValidatingInstanceReader;
class VariableLoader;
};
@@ -79,8 +81,11 @@ class Q_XMLPATTERNS_EXPORT QXmlQuery
public:
enum QueryLanguage
{
- XQuery10 = 1,
- XSLT20 = 2
+ XQuery10 = 1,
+ XSLT20 = 2,
+ XmlSchema11IdentityConstraintSelector = 1024,
+ XmlSchema11IdentityConstraintField = 2048,
+ XPath20 = 4096
};
QXmlQuery();
@@ -135,6 +140,8 @@ private:
friend class QXmlName;
friend class QXmlSerializer;
friend class QPatternistSDK::TestCase;
+ friend class QPatternist::XsdSchemaParser;
+ friend class QPatternist::XsdValidatingInstanceReader;
friend class QPatternist::VariableLoader;
template<typename TInputType> friend bool setFocusHelper(QXmlQuery *const queryInstance,
const TInputType &focusValue);
diff --git a/src/xmlpatterns/api/qxmlquery_p.h b/src/xmlpatterns/api/qxmlquery_p.h
index c8ed4412ca..7f58f974f8 100644
--- a/src/xmlpatterns/api/qxmlquery_p.h
+++ b/src/xmlpatterns/api/qxmlquery_p.h
@@ -142,13 +142,10 @@ public:
if(!m_functionFactory)
{
- if(queryLanguage == QXmlQuery::XQuery10)
- m_functionFactory = QPatternist::FunctionFactoryCollection::xpath20Factory(namePool.d);
- else
- {
- Q_ASSERT(queryLanguage == QXmlQuery::XSLT20);
+ if(queryLanguage == QXmlQuery::XSLT20)
m_functionFactory = QPatternist::FunctionFactoryCollection::xslt20Factory(namePool.d);
- }
+ else
+ m_functionFactory = QPatternist::FunctionFactoryCollection::xpath20Factory(namePool.d);
}
const QPatternist::GenericStaticContext::Ptr genericStaticContext(new QPatternist::GenericStaticContext(namePool.d,
@@ -164,6 +161,14 @@ public:
if(!contextItem.isNull())
m_staticContext = QPatternist::StaticContext::Ptr(new QPatternist::StaticFocusContext(QPatternist::AtomicValue::qtToXDMType(contextItem), m_staticContext));
+ else if( queryLanguage == QXmlQuery::XmlSchema11IdentityConstraintField
+ || queryLanguage == QXmlQuery::XmlSchema11IdentityConstraintSelector
+ || queryLanguage == QXmlQuery::XPath20)
+ m_staticContext = QPatternist::StaticContext::Ptr(new QPatternist::StaticFocusContext(QPatternist::BuiltinTypes::node, m_staticContext));
+
+ for (int i = 0; i < m_additionalNamespaceBindings.count(); ++i) {
+ m_staticContext->namespaceBindings()->addBinding(m_additionalNamespaceBindings.at(i));
+ }
return m_staticContext;
}
@@ -278,6 +283,11 @@ public:
return m_expr;
}
+ inline void addAdditionalNamespaceBinding(const QXmlName &binding)
+ {
+ m_additionalNamespaceBindings.append(binding);
+ }
+
QXmlNamePool namePool;
QPointer<QAbstractMessageHandler> messageHandler;
/**
@@ -321,6 +331,8 @@ public:
QPatternist::SequenceType::Ptr m_requiredType;
QPatternist::FunctionFactory::Ptr m_functionFactory;
QPatternist::NetworkAccessDelegator::Ptr m_networkAccessDelegator;
+
+ QList<QXmlName> m_additionalNamespaceBindings;
};
QT_END_NAMESPACE
diff --git a/src/xmlpatterns/api/qxmlschema.cpp b/src/xmlpatterns/api/qxmlschema.cpp
new file mode 100644
index 0000000000..55b96cdcd3
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlschema.cpp
@@ -0,0 +1,229 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the $MODULE$ of the Qt Toolkit.
+**
+** $TROLLTECH_DUAL_LICENSE$
+**
+****************************************************************************/
+
+#include "qxmlschema.h"
+#include "qxmlschema_p.h"
+
+#include <QtCore/QIODevice>
+#include <QtCore/QUrl>
+
+/*!
+ \class QXmlSchema
+
+ \brief The QXmlSchema class provides loading and validation of a W3C XML Schema.
+
+ \reentrant
+ \since 4.X
+ \ingroup xml-tools
+
+ The QXmlSchema class loads, compiles and validates W3C XML Schema files
+ that can be used further for validation of XML instance documents via
+ \l{QXmlSchemaValidator}.
+*/
+
+/*!
+ Constructs an invalid, empty schema that cannot be used until
+ setSchema() is called.
+ */
+QXmlSchema::QXmlSchema()
+ : d(new QXmlSchemaPrivate(QXmlNamePool()))
+{
+}
+
+/*!
+ Constructs a QXmlSchema that is a copy of \a other. The new
+ instance will share resources with the existing schema
+ to the extent possible.
+ */
+QXmlSchema::QXmlSchema(const QXmlSchema &other)
+ : d(other.d)
+{
+}
+
+/*!
+ Destroys this QXmlSchema.
+ */
+QXmlSchema::~QXmlSchema()
+{
+}
+
+/*!
+ Sets this QXmlSchema to a schema loaded from the \a source
+ URI.
+ */
+void QXmlSchema::load(const QUrl &source)
+{
+ d->load(source, QString());
+}
+
+/*!
+ Sets this QXmlSchema to a schema read from the \a source
+ device. The device must have been opened with at least
+ QIODevice::ReadOnly.
+
+ \a documentUri represents the schema obtained from the \a source
+ device. It is the base URI of the schema, that is used
+ internally to resolve relative URIs that appear in the schema, and
+ for message reporting.
+
+ If \a source is \c null or not readable, or if \a documentUri is not
+ a valid URI, behavior is undefined.
+ \sa isValid()
+ */
+void QXmlSchema::load(QIODevice *source, const QUrl &documentUri)
+{
+ d->load(source, documentUri, QString());
+}
+
+/*!
+ Sets this QXmlSchema to a schema read from the \a data
+
+ \a documentUri represents the schema obtained from the \a data.
+ It is the base URI of the schema, that is used internally to
+ resolve relative URIs that appear in the schema, and
+ for message reporting.
+
+ If \a documentUri is not a valid URI, behavior is undefined.
+ \sa isValid()
+ */
+void QXmlSchema::load(const QByteArray &data, const QUrl &documentUri)
+{
+ d->load(data, documentUri, QString());
+}
+
+/*!
+ Returns true if this schema is valid. Examples of invalid schemas
+ are ones that contain syntax errors or that do not conform the
+ W3C XML Schema specification.
+ */
+bool QXmlSchema::isValid() const
+{
+ return d->isValid();
+}
+
+/*!
+ Returns the name pool used by this QXmlSchema for constructing \l
+ {QXmlName} {names}. There is no setter for the name pool, because
+ mixing name pools causes errors due to name confusion.
+ */
+QXmlNamePool QXmlSchema::namePool() const
+{
+ return d->namePool();
+}
+
+/*!
+ Returns the document URI of the schema or an empty URI if no
+ schema has been set.
+ */
+QUrl QXmlSchema::documentUri() const
+{
+ return d->documentUri();
+}
+
+/*!
+ Changes the \l {QAbstractMessageHandler}{message handler} for this
+ QXmlSchema to \a handler. The schema sends all compile and
+ validation messages to this message handler. QXmlSchema does not take
+ ownership of \a handler.
+
+ Normally, the default message handler is sufficient. It writes
+ compile and validation messages to \e stderr. The default message
+ handler includes color codes if \e stderr can render colors.
+
+ When QXmlSchema calls QAbstractMessageHandler::message(),
+ the arguments are as follows:
+
+ \table
+ \header
+ \o message() argument
+ \o Semantics
+ \row
+ \o QtMsgType type
+ \o Only QtWarningMsg and QtFatalMsg are used. The former
+ identifies a warning, while the latter identifies an error.
+ \row
+ \o const QString & description
+ \o An XHTML document which is the actual message. It is translated
+ into the current language.
+ \row
+ \o const QUrl &identifier
+ \o Identifies the error with a URI, where the fragment is
+ the error code, and the rest of the URI is the error namespace.
+ \row
+ \o const QSourceLocation & sourceLocation
+ \o Identifies where the error occurred.
+ \endtable
+
+ */
+void QXmlSchema::setMessageHandler(QAbstractMessageHandler *handler)
+{
+ d->setMessageHandler(handler);
+}
+
+/*!
+ Returns the message handler that handles compile and validation
+ messages for this QXmlSchema.
+ */
+QAbstractMessageHandler *QXmlSchema::messageHandler() const
+{
+ return d->messageHandler();
+}
+
+/*!
+ Sets the URI resolver to \a resolver. QXmlSchema does not take
+ ownership of \a resolver.
+
+ \sa uriResolver()
+ */
+void QXmlSchema::setUriResolver(QAbstractUriResolver *resolver)
+{
+ d->setUriResolver(resolver);
+}
+
+/*!
+ Returns the schema's URI resolver. If no URI resolver has been set,
+ QtXmlPatterns will use the URIs in queries as they are.
+
+ The URI resolver provides a level of abstraction, or \e{polymorphic
+ URIs}. A resolver can rewrite \e{logical} URIs to physical ones, or
+ it can translate obsolete or invalid URIs to valid ones.
+
+ When QtXmlPatterns calls QAbstractUriResolver::resolve() the
+ absolute URI is the URI mandated by the schema specification, and the
+ relative URI is the URI specified by the user.
+
+ \sa setUriResolver()
+ */
+QAbstractUriResolver *QXmlSchema::uriResolver() const
+{
+ return d->uriResolver();
+}
+
+/*!
+ Sets the network manager to \a manager.
+ QXmlSchema does not take ownership of \a manager.
+
+ \sa networkAccessManager()
+ */
+void QXmlSchema::setNetworkAccessManager(QNetworkAccessManager *manager)
+{
+ d->setNetworkAccessManager(manager);
+}
+
+/*!
+ Returns the network manager, or 0 if it has not been set.
+
+ \sa setNetworkAccessManager()
+ */
+QNetworkAccessManager *QXmlSchema::networkAccessManager() const
+{
+ return d->networkAccessManager();
+}
diff --git a/src/xmlpatterns/api/qxmlschema.h b/src/xmlpatterns/api/qxmlschema.h
new file mode 100644
index 0000000000..225cce2074
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlschema.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the $MODULE$ of the Qt Toolkit.
+**
+** $TROLLTECH_DUAL_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXMLSCHEMA_H
+#define QXMLSCHEMA_H
+
+#include <QtCore/QSharedDataPointer>
+#include <QtXmlPatterns/QXmlNamePool>
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(XmlPatterns)
+
+class QAbstractMessageHandler;
+class QAbstractUriResolver;
+class QIODevice;
+class QNetworkAccessManager;
+class QUrl;
+class QXmlNamePool;
+class QXmlSchemaPrivate;
+
+class Q_XMLPATTERNS_EXPORT QXmlSchema
+{
+ friend class QXmlSchemaValidatorPrivate;
+
+ public:
+ QXmlSchema();
+ QXmlSchema(const QXmlSchema &other);
+ ~QXmlSchema();
+
+ void load(const QUrl &source);
+ void load(QIODevice *source, const QUrl &documentUri);
+ void load(const QByteArray &data, const QUrl &documentUri);
+
+ bool isValid() const;
+
+ QXmlNamePool namePool() const;
+ QUrl documentUri() const;
+
+ void setMessageHandler(QAbstractMessageHandler *handler);
+ QAbstractMessageHandler *messageHandler() const;
+
+ void setUriResolver(QAbstractUriResolver *resolver);
+ QAbstractUriResolver *uriResolver() const;
+
+ void setNetworkAccessManager(QNetworkAccessManager *networkmanager);
+ QNetworkAccessManager *networkAccessManager() const;
+
+ private:
+ QSharedDataPointer<QXmlSchemaPrivate> d;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qxmlschema_p.cpp b/src/xmlpatterns/api/qxmlschema_p.cpp
new file mode 100644
index 0000000000..ebcccee023
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlschema_p.cpp
@@ -0,0 +1,169 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the $MODULE$ of the Qt Toolkit.
+**
+** $TROLLTECH_DUAL_LICENSE$
+**
+****************************************************************************/
+
+#include "qacceltreeresourceloader_p.h"
+#include "qxmlschema.h"
+#include "qxmlschema_p.h"
+
+#include <QtCore/QBuffer>
+#include <QtCore/QIODevice>
+#include <QtCore/QUrl>
+
+QXmlSchemaPrivate::QXmlSchemaPrivate(const QXmlNamePool &namePool)
+ : m_namePool(namePool)
+ , m_userMessageHandler(0)
+ , m_uriResolver(0)
+ , m_userNetworkAccessManager(0)
+ , m_schemaContext(new QPatternist::XsdSchemaContext(m_namePool.d))
+ , m_schemaParserContext(new QPatternist::XsdSchemaParserContext(m_namePool.d, m_schemaContext))
+ , m_schemaIsValid(false)
+{
+ m_networkAccessManager = new QPatternist::ReferenceCountedValue<QNetworkAccessManager>(new QNetworkAccessManager());
+ m_messageHandler = new QPatternist::ReferenceCountedValue<QAbstractMessageHandler>(new QPatternist::ColoringMessageHandler());
+}
+
+QXmlSchemaPrivate::QXmlSchemaPrivate(const QPatternist::XsdSchemaContext::Ptr &schemaContext)
+ : m_namePool(QXmlNamePool(schemaContext->namePool().data()))
+ , m_userMessageHandler(0)
+ , m_uriResolver(0)
+ , m_userNetworkAccessManager(0)
+ , m_schemaContext(schemaContext)
+ , m_schemaParserContext(new QPatternist::XsdSchemaParserContext(m_namePool.d, m_schemaContext))
+ , m_schemaIsValid(false)
+{
+ m_networkAccessManager = new QPatternist::ReferenceCountedValue<QNetworkAccessManager>(new QNetworkAccessManager());
+ m_messageHandler = new QPatternist::ReferenceCountedValue<QAbstractMessageHandler>(new QPatternist::ColoringMessageHandler());
+}
+
+QXmlSchemaPrivate::QXmlSchemaPrivate(const QXmlSchemaPrivate &other)
+ : QSharedData(other)
+{
+ m_namePool = other.m_namePool;
+ m_userMessageHandler = other.m_userMessageHandler;
+ m_uriResolver = other.m_uriResolver;
+ m_userNetworkAccessManager = other.m_userNetworkAccessManager;
+ m_messageHandler = other.m_messageHandler;
+ m_networkAccessManager = other.m_networkAccessManager;
+
+ m_schemaContext = other.m_schemaContext;
+ m_schemaParserContext = other.m_schemaParserContext;
+ m_schemaIsValid = other.m_schemaIsValid;
+ m_documentUri = other.m_documentUri;
+}
+
+void QXmlSchemaPrivate::load(const QUrl &source, const QString &targetNamespace)
+{
+ m_documentUri = source;
+
+ m_schemaContext->setMessageHandler(messageHandler());
+ m_schemaContext->setUriResolver(uriResolver());
+ m_schemaContext->setNetworkAccessManager(networkAccessManager());
+
+ const QPatternist::AutoPtr<QNetworkReply> reply(QPatternist::AccelTreeResourceLoader::load(source, m_schemaContext->networkAccessManager(),
+ m_schemaContext, QPatternist::AccelTreeResourceLoader::ContinueOnError));
+ if (reply)
+ load(reply.data(), source, targetNamespace);
+}
+
+void QXmlSchemaPrivate::load(const QByteArray &data, const QUrl &documentUri, const QString &targetNamespace)
+{
+ QByteArray localData(data);
+
+ QBuffer buffer(&localData);
+ buffer.open(QIODevice::ReadOnly);
+
+ load(&buffer, documentUri, targetNamespace);
+}
+
+void QXmlSchemaPrivate::load(QIODevice *source, const QUrl &documentUri, const QString &targetNamespace)
+{
+ m_schemaParserContext = QPatternist::XsdSchemaParserContext::Ptr(new QPatternist::XsdSchemaParserContext(m_namePool.d, m_schemaContext));
+ m_schemaIsValid = false;
+
+ if (!source) {
+ qWarning("A null QIODevice pointer cannot be passed.");
+ return;
+ }
+
+ if (!source->isReadable()) {
+ qWarning("The device must be readable.");
+ return;
+ }
+
+ m_documentUri = documentUri;
+ m_schemaContext->setMessageHandler(messageHandler());
+ m_schemaContext->setUriResolver(uriResolver());
+ m_schemaContext->setNetworkAccessManager(networkAccessManager());
+
+ QPatternist::XsdSchemaParser parser(m_schemaContext, m_schemaParserContext, source);
+ parser.setDocumentURI(documentUri);
+ parser.setTargetNamespace(targetNamespace);
+
+ try {
+ parser.parse();
+ m_schemaParserContext->resolver()->resolve();
+
+ m_schemaIsValid = true;
+ } catch (QPatternist::Exception exception) {
+ m_schemaIsValid = false;
+ }
+}
+
+bool QXmlSchemaPrivate::isValid() const
+{
+ return m_schemaIsValid;
+}
+
+QXmlNamePool QXmlSchemaPrivate::namePool() const
+{
+ return m_namePool;
+}
+
+QUrl QXmlSchemaPrivate::documentUri() const
+{
+ return m_documentUri;
+}
+
+void QXmlSchemaPrivate::setMessageHandler(QAbstractMessageHandler *handler)
+{
+ m_userMessageHandler = handler;
+}
+
+QAbstractMessageHandler *QXmlSchemaPrivate::messageHandler() const
+{
+ if (m_userMessageHandler)
+ return m_userMessageHandler;
+
+ return m_messageHandler.data()->value;
+}
+
+void QXmlSchemaPrivate::setUriResolver(QAbstractUriResolver *resolver)
+{
+ m_uriResolver = resolver;
+}
+
+QAbstractUriResolver *QXmlSchemaPrivate::uriResolver() const
+{
+ return m_uriResolver;
+}
+
+void QXmlSchemaPrivate::setNetworkAccessManager(QNetworkAccessManager *networkmanager)
+{
+ m_userNetworkAccessManager = networkmanager;
+}
+
+QNetworkAccessManager *QXmlSchemaPrivate::networkAccessManager() const
+{
+ if (m_userNetworkAccessManager)
+ return m_userNetworkAccessManager;
+
+ return m_networkAccessManager.data()->value;
+}
diff --git a/src/xmlpatterns/api/qxmlschema_p.h b/src/xmlpatterns/api/qxmlschema_p.h
new file mode 100644
index 0000000000..e625f1eb16
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlschema_p.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the $MODULE$ of the Qt Toolkit.
+**
+** $TROLLTECH_DUAL_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef QXMLSCHEMA_P_H
+#define QXMLSCHEMA_P_H
+
+#include "qabstractmessagehandler.h"
+#include "qabstracturiresolver.h"
+#include "qautoptr_p.h"
+#include "qcoloringmessagehandler_p.h"
+#include "qreferencecountedvalue_p.h"
+
+#include "qxsdschemacontext_p.h"
+#include "qxsdschemaparser_p.h"
+#include "qxsdschemaparsercontext_p.h"
+
+#include <QtCore/QSharedData>
+#include <QtNetwork/QNetworkAccessManager>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QXmlSchemaPrivate : public QSharedData
+{
+ public:
+ QXmlSchemaPrivate(const QXmlNamePool &namePool);
+ QXmlSchemaPrivate(const QPatternist::XsdSchemaContext::Ptr &schemaContext);
+ QXmlSchemaPrivate(const QXmlSchemaPrivate &other);
+
+ void load(const QUrl &source, const QString &targetNamespace);
+ void load(QIODevice *source, const QUrl &documentUri, const QString &targetNamespace);
+ void load(const QByteArray &data, const QUrl &documentUri, const QString &targetNamespace);
+ bool isValid() const;
+ QXmlNamePool namePool() const;
+ QUrl documentUri() const;
+ void setMessageHandler(QAbstractMessageHandler *handler);
+ QAbstractMessageHandler *messageHandler() const;
+ void setUriResolver(QAbstractUriResolver *resolver);
+ QAbstractUriResolver *uriResolver() const;
+ void setNetworkAccessManager(QNetworkAccessManager *networkmanager);
+ QNetworkAccessManager *networkAccessManager() const;
+
+ QXmlNamePool m_namePool;
+ QAbstractMessageHandler* m_userMessageHandler;
+ QAbstractUriResolver* m_uriResolver;
+ QNetworkAccessManager* m_userNetworkAccessManager;
+ QPatternist::ReferenceCountedValue<QAbstractMessageHandler>::Ptr m_messageHandler;
+ QPatternist::ReferenceCountedValue<QNetworkAccessManager>::Ptr m_networkAccessManager;
+
+ QPatternist::XsdSchemaContext::Ptr m_schemaContext;
+ QPatternist::XsdSchemaParserContext::Ptr m_schemaParserContext;
+ bool m_schemaIsValid;
+ QUrl m_documentUri;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qxmlschemavalidator.cpp b/src/xmlpatterns/api/qxmlschemavalidator.cpp
new file mode 100644
index 0000000000..aa80537d55
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlschemavalidator.cpp
@@ -0,0 +1,264 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the $MODULE$ of the Qt Toolkit.
+**
+** $TROLLTECH_DUAL_LICENSE$
+**
+****************************************************************************/
+
+#include "qxmlschemavalidator.h"
+#include "qxmlschemavalidator_p.h"
+
+#include "qacceltreeresourceloader_p.h"
+#include "qxmlschema.h"
+#include "qxmlschema_p.h"
+#include "qxsdvalidatinginstancereader_p.h"
+
+#include <QtCore/QBuffer>
+#include <QtCore/QIODevice>
+#include <QtCore/QUrl>
+
+/*!
+ \class QXmlSchemaValidator
+
+ \brief The QXmlSchemaValidator class validates XML instance documents against a W3C XML Schema.
+
+ \reentrant
+ \since 4.X
+ \ingroup xml-tools
+
+ The QXmlSchemaValidator class loads, parses an XML instance document and validates it
+ against a W3C XML Schema that has been compiled with \l{QXmlSchema}.
+*/
+
+/*!
+ Constructs a schema validator that will use \a schema for validation.
+ */
+QXmlSchemaValidator::QXmlSchemaValidator(const QXmlSchema &schema)
+ : d(new QXmlSchemaValidatorPrivate(schema))
+{
+}
+
+/*!
+ Destroys this QXmlSchemaValidator.
+ */
+QXmlSchemaValidator::~QXmlSchemaValidator()
+{
+ delete d;
+}
+
+/*!
+ Sets the \a schema that shall be used for further validation.
+ */
+void QXmlSchemaValidator::setSchema(const QXmlSchema &schema)
+{
+ d->setSchema(schema);
+}
+
+/*!
+ Validates the XML instance document read from \a data with the
+ given \a documentUri against the schema.
+
+ Returns \c true if the XML instance document is valid according the
+ schema, \c false otherwise.
+ */
+bool QXmlSchemaValidator::validate(const QByteArray &data, const QUrl &documentUri)
+{
+ QByteArray localData(data);
+
+ QBuffer buffer(&localData);
+ buffer.open(QIODevice::ReadOnly);
+
+ return validate(&buffer, documentUri);
+}
+
+/*!
+ Validates the XML instance document read from \a source against the schema.
+
+ Returns \c true if the XML instance document is valid according the
+ schema, \c false otherwise.
+ */
+bool QXmlSchemaValidator::validate(const QUrl &source)
+{
+ d->m_context->setMessageHandler(messageHandler());
+ d->m_context->setUriResolver(uriResolver());
+ d->m_context->setNetworkAccessManager(networkAccessManager());
+
+ const QPatternist::AutoPtr<QNetworkReply> reply(QPatternist::AccelTreeResourceLoader::load(source, d->m_context->networkAccessManager(),
+ d->m_context, QPatternist::AccelTreeResourceLoader::ContinueOnError));
+ if (reply)
+ return validate(reply.data(), source);
+ else
+ return false;
+}
+
+/*!
+ Validates the XML instance document read from \a source with the
+ given \a documentUri against the schema.
+
+ Returns \c true if the XML instance document is valid according the
+ schema, \c false otherwise.
+ */
+bool QXmlSchemaValidator::validate(QIODevice *source, const QUrl &documentUri)
+{
+ if (!source) {
+ qWarning("A null QIODevice pointer cannot be passed.");
+ return false;
+ }
+
+ if (!source->isReadable()) {
+ qWarning("The device must be readable.");
+ return false;
+ }
+
+ d->m_context->setMessageHandler(messageHandler());
+ d->m_context->setUriResolver(uriResolver());
+ d->m_context->setNetworkAccessManager(networkAccessManager());
+
+ QPatternist::NetworkAccessDelegator::Ptr delegator(new QPatternist::NetworkAccessDelegator(d->m_context->networkAccessManager(),
+ d->m_context->networkAccessManager()));
+
+ QPatternist::AccelTreeResourceLoader loader(d->m_context->namePool(), delegator, QPatternist::AccelTreeBuilder<true>::SourceLocationsFeature);
+
+ QPatternist::Item item;
+ try {
+ item = loader.openDocument(source, documentUri, d->m_context);
+ } catch (QPatternist::Exception exception) {
+ return false;
+ }
+
+ QXmlNodeModelIndex index = item.asNode();
+ const QAbstractXmlNodeModel *model = item.asNode().model();
+
+ QPatternist::XsdValidatedXmlNodeModel *validatedModel = new QPatternist::XsdValidatedXmlNodeModel(model);
+
+ QPatternist::XsdValidatingInstanceReader reader(validatedModel, documentUri, d->m_context);
+ if (d->m_schema)
+ reader.addSchema(d->m_schema, d->m_schemaDocumentUri);
+ try {
+ reader.read();
+ } catch (QPatternist::Exception exception) {
+ return false;
+ }
+
+ return true;
+}
+
+/*!
+ Returns the name pool used by this QXmlSchemaValidator for constructing \l
+ {QXmlName} {names}. There is no setter for the name pool, because
+ mixing name pools causes errors due to name confusion.
+ */
+QXmlNamePool QXmlSchemaValidator::namePool() const
+{
+ return d->m_namePool;
+}
+
+/*!
+ Changes the \l {QAbstractMessageHandler}{message handler} for this
+ QXmlSchemaValidator to \a handler. The schema validator sends all parsing and
+ validation messages to this message handler. QXmlSchemaValidator does not take
+ ownership of \a handler.
+
+ Normally, the default message handler is sufficient. It writes
+ compile and validation messages to \e stderr. The default message
+ handler includes color codes if \e stderr can render colors.
+
+ When QXmlSchemaValidator calls QAbstractMessageHandler::message(),
+ the arguments are as follows:
+
+ \table
+ \header
+ \o message() argument
+ \o Semantics
+ \row
+ \o QtMsgType type
+ \o Only QtWarningMsg and QtFatalMsg are used. The former
+ identifies a warning, while the latter identifies an error.
+ \row
+ \o const QString & description
+ \o An XHTML document which is the actual message. It is translated
+ into the current language.
+ \row
+ \o const QUrl &identifier
+ \o Identifies the error with a URI, where the fragment is
+ the error code, and the rest of the URI is the error namespace.
+ \row
+ \o const QSourceLocation & sourceLocation
+ \o Identifies where the error occurred.
+ \endtable
+
+ */
+void QXmlSchemaValidator::setMessageHandler(QAbstractMessageHandler *handler)
+{
+ d->m_userMessageHandler = handler;
+}
+
+/*!
+ Returns the message handler that handles parsing and validation
+ messages for this QXmlSchemaValidator.
+ */
+QAbstractMessageHandler *QXmlSchemaValidator::messageHandler() const
+{
+ if (d->m_userMessageHandler)
+ return d->m_userMessageHandler;
+
+ return d->m_messageHandler.data()->value;
+}
+
+/*!
+ Sets the URI resolver to \a resolver. QXmlSchemaValidator does not take
+ ownership of \a resolver.
+
+ \sa uriResolver()
+ */
+void QXmlSchemaValidator::setUriResolver(QAbstractUriResolver *resolver)
+{
+ d->m_uriResolver = resolver;
+}
+
+/*!
+ Returns the schema's URI resolver. If no URI resolver has been set,
+ QtXmlPatterns will use the URIs in queries as they are.
+
+ The URI resolver provides a level of abstraction, or \e{polymorphic
+ URIs}. A resolver can rewrite \e{logical} URIs to physical ones, or
+ it can translate obsolete or invalid URIs to valid ones.
+
+ When QtXmlPatterns calls QAbstractUriResolver::resolve() the
+ absolute URI is the URI mandated by the schema specification, and the
+ relative URI is the URI specified by the user.
+
+ \sa setUriResolver()
+ */
+QAbstractUriResolver *QXmlSchemaValidator::uriResolver() const
+{
+ return d->m_uriResolver;
+}
+
+/*!
+ Sets the network manager to \a manager.
+ QXmlSchemaValidator does not take ownership of \a manager.
+
+ \sa networkAccessManager()
+ */
+void QXmlSchemaValidator::setNetworkAccessManager(QNetworkAccessManager *manager)
+{
+ d->m_userNetworkAccessManager = manager;
+}
+
+/*!
+ Returns the network manager, or 0 if it has not been set.
+
+ \sa setNetworkAccessManager()
+ */
+QNetworkAccessManager *QXmlSchemaValidator::networkAccessManager() const
+{
+ if (d->m_userNetworkAccessManager)
+ return d->m_userNetworkAccessManager;
+
+ return d->m_networkAccessManager.data()->value;
+}
diff --git a/src/xmlpatterns/api/qxmlschemavalidator.h b/src/xmlpatterns/api/qxmlschemavalidator.h
new file mode 100644
index 0000000000..e643995be0
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlschemavalidator.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the $MODULE$ of the Qt Toolkit.
+**
+** $TROLLTECH_DUAL_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXMLSCHEMAVALIDATOR_H
+#define QXMLSCHEMAVALIDATOR_H
+
+#include <QtXmlPatterns/QXmlNamePool>
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(XmlPatterns)
+
+class QAbstractMessageHandler;
+class QAbstractUriResolver;
+class QIODevice;
+class QNetworkAccessManager;
+class QUrl;
+class QXmlNamePool;
+class QXmlSchema;
+class QXmlSchemaValidatorPrivate;
+
+class Q_XMLPATTERNS_EXPORT QXmlSchemaValidator
+{
+ public:
+ QXmlSchemaValidator(const QXmlSchema &schema);
+ ~QXmlSchemaValidator();
+
+ void setSchema(const QXmlSchema &schema);
+
+ bool validate(const QUrl &source);
+ bool validate(QIODevice *source, const QUrl &documentUri);
+ bool validate(const QByteArray &data, const QUrl &documentUri);
+
+ QXmlNamePool namePool() const;
+
+ void setMessageHandler(QAbstractMessageHandler *handler);
+ QAbstractMessageHandler *messageHandler() const;
+
+ void setUriResolver(QAbstractUriResolver *resolver);
+ QAbstractUriResolver *uriResolver() const;
+
+ void setNetworkAccessManager(QNetworkAccessManager *networkmanager);
+ QNetworkAccessManager *networkAccessManager() const;
+
+ private:
+ QXmlSchemaValidatorPrivate* const d;
+
+ Q_DISABLE_COPY(QXmlSchemaValidator)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qxmlschemavalidator_p.h b/src/xmlpatterns/api/qxmlschemavalidator_p.h
new file mode 100644
index 0000000000..0990f73168
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlschemavalidator_p.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the $MODULE$ of the Qt Toolkit.
+**
+** $TROLLTECH_DUAL_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef QXMLSCHEMAVALIDATOR_P_H
+#define QXMLSCHEMAVALIDATOR_P_H
+
+#include "qabstractmessagehandler.h"
+#include "qabstracturiresolver.h"
+#include "qautoptr_p.h"
+#include "qcoloringmessagehandler_p.h"
+#include "qxmlschema.h"
+#include "qxmlschema_p.h"
+
+#include "qxsdschemacontext_p.h"
+#include "qxsdschema_p.h"
+
+#include <QtNetwork/QNetworkAccessManager>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QXmlSchemaValidatorPrivate
+{
+public:
+ QXmlSchemaValidatorPrivate(const QXmlSchema &schema)
+ : m_namePool(schema.namePool())
+ , m_userMessageHandler(0)
+ , m_uriResolver(0)
+ , m_userNetworkAccessManager(0)
+ {
+ setSchema(schema);
+
+ const QXmlSchemaPrivate *p = schema.d;
+
+ // initialize the environment properties with the ones from the schema
+
+ if (p->m_userNetworkAccessManager) // schema has user defined network access manager
+ m_userNetworkAccessManager = p->m_userNetworkAccessManager;
+ else
+ m_networkAccessManager = p->m_networkAccessManager;
+
+ if (p->m_userMessageHandler) // schema has user defined message handler
+ m_userMessageHandler = p->m_userMessageHandler;
+ else
+ m_messageHandler = p->m_messageHandler;
+
+ m_uriResolver = p->m_uriResolver;
+ }
+
+ void setSchema(const QXmlSchema &schema)
+ {
+ // use same name pool as the schema
+ m_namePool = schema.namePool();
+ m_schema = schema.d->m_schemaParserContext->schema();
+ m_schemaDocumentUri = schema.documentUri();
+
+ // create a new schema context
+ m_context = QPatternist::XsdSchemaContext::Ptr(new QPatternist::XsdSchemaContext(m_namePool.d));
+ m_context->m_schemaTypeFactory = schema.d->m_schemaContext->m_schemaTypeFactory;
+ m_context->m_builtinTypesFacetList = schema.d->m_schemaContext->m_builtinTypesFacetList;
+ }
+
+ QXmlNamePool m_namePool;
+ QAbstractMessageHandler* m_userMessageHandler;
+ QAbstractUriResolver* m_uriResolver;
+ QNetworkAccessManager* m_userNetworkAccessManager;
+ QPatternist::ReferenceCountedValue<QAbstractMessageHandler>::Ptr m_messageHandler;
+ QPatternist::ReferenceCountedValue<QNetworkAccessManager>::Ptr m_networkAccessManager;
+
+ QPatternist::XsdSchemaContext::Ptr m_context;
+ QPatternist::XsdSchema::Ptr m_schema;
+ QUrl m_schemaDocumentUri;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif