diff options
29 files changed, 521 insertions, 186 deletions
diff --git a/src/xmlpatterns/api/qxmlquery.cpp b/src/xmlpatterns/api/qxmlquery.cpp index 423da3e..1cf0a2e 100644 --- a/src/xmlpatterns/api/qxmlquery.cpp +++ b/src/xmlpatterns/api/qxmlquery.cpp @@ -427,7 +427,7 @@ void QXmlQuery::setQuery(QIODevice *sourceCode, const QUrl &documentURI) return; } - d->queryURI = QXmlQueryPrivate::normalizeQueryURI(documentURI); + d->queryURI = QPatternist::XPathHelper::normalizeQueryURI(documentURI); d->expression(sourceCode); } @@ -475,12 +475,12 @@ void QXmlQuery::setQuery(const QUrl &queryURI, const QUrl &baseURI) { Q_ASSERT_X(queryURI.isValid(), Q_FUNC_INFO, "The passed URI must be valid."); - const QUrl canonicalURI(QXmlQueryPrivate::normalizeQueryURI(queryURI)); + const QUrl canonicalURI(QPatternist::XPathHelper::normalizeQueryURI(queryURI)); Q_ASSERT(canonicalURI.isValid()); Q_ASSERT(!canonicalURI.isRelative()); Q_ASSERT(baseURI.isValid() || baseURI.isEmpty()); - d->queryURI = QXmlQueryPrivate::normalizeQueryURI(baseURI.isEmpty() ? queryURI : baseURI); + d->queryURI = QPatternist::XPathHelper::normalizeQueryURI(baseURI.isEmpty() ? queryURI : baseURI); QPatternist::AutoPtr<QIODevice> result; diff --git a/src/xmlpatterns/api/qxmlquery_p.h b/src/xmlpatterns/api/qxmlquery_p.h index 7f58f97..486d885 100644 --- a/src/xmlpatterns/api/qxmlquery_p.h +++ b/src/xmlpatterns/api/qxmlquery_p.h @@ -212,19 +212,6 @@ public: return m_resourceLoader; } - - static inline QUrl normalizeQueryURI(const QUrl &uri) - { - Q_ASSERT_X(uri.isEmpty() || uri.isValid(), Q_FUNC_INFO, - "The URI passed to QXmlQuery::setQuery() must be valid or empty."); - if(uri.isEmpty()) - return QUrl::fromLocalFile(QCoreApplication::applicationFilePath()); - else if(uri.isRelative()) - return QUrl::fromLocalFile(QCoreApplication::applicationFilePath()).resolved(uri); - else - return uri; - } - void setRequiredType(const QPatternist::SequenceType::Ptr &seqType) { Q_ASSERT(seqType); diff --git a/src/xmlpatterns/api/qxmlschema.cpp b/src/xmlpatterns/api/qxmlschema.cpp index 55b96cd..108212e 100644 --- a/src/xmlpatterns/api/qxmlschema.cpp +++ b/src/xmlpatterns/api/qxmlschema.cpp @@ -21,7 +21,7 @@ \brief The QXmlSchema class provides loading and validation of a W3C XML Schema. \reentrant - \since 4.X + \since 4.6 \ingroup xml-tools The QXmlSchema class loads, compiles and validates W3C XML Schema files @@ -31,7 +31,7 @@ /*! Constructs an invalid, empty schema that cannot be used until - setSchema() is called. + load() is called. */ QXmlSchema::QXmlSchema() : d(new QXmlSchemaPrivate(QXmlNamePool())) @@ -59,9 +59,10 @@ QXmlSchema::~QXmlSchema() Sets this QXmlSchema to a schema loaded from the \a source URI. */ -void QXmlSchema::load(const QUrl &source) +bool QXmlSchema::load(const QUrl &source) { d->load(source, QString()); + return d->isValid(); } /*! @@ -78,9 +79,10 @@ void QXmlSchema::load(const QUrl &source) a valid URI, behavior is undefined. \sa isValid() */ -void QXmlSchema::load(QIODevice *source, const QUrl &documentUri) +bool QXmlSchema::load(QIODevice *source, const QUrl &documentUri) { d->load(source, documentUri, QString()); + return d->isValid(); } /*! @@ -94,9 +96,10 @@ void QXmlSchema::load(QIODevice *source, const QUrl &documentUri) If \a documentUri is not a valid URI, behavior is undefined. \sa isValid() */ -void QXmlSchema::load(const QByteArray &data, const QUrl &documentUri) +bool QXmlSchema::load(const QByteArray &data, const QUrl &documentUri) { d->load(data, documentUri, QString()); + return d->isValid(); } /*! @@ -183,14 +186,14 @@ QAbstractMessageHandler *QXmlSchema::messageHandler() const \sa uriResolver() */ -void QXmlSchema::setUriResolver(QAbstractUriResolver *resolver) +void QXmlSchema::setUriResolver(const 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. + QtXmlPatterns will use the URIs in schemas 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 @@ -202,7 +205,7 @@ void QXmlSchema::setUriResolver(QAbstractUriResolver *resolver) \sa setUriResolver() */ -QAbstractUriResolver *QXmlSchema::uriResolver() const +const QAbstractUriResolver *QXmlSchema::uriResolver() const { return d->uriResolver(); } diff --git a/src/xmlpatterns/api/qxmlschema.h b/src/xmlpatterns/api/qxmlschema.h index 225cce2..cf56b1e 100644 --- a/src/xmlpatterns/api/qxmlschema.h +++ b/src/xmlpatterns/api/qxmlschema.h @@ -13,6 +13,7 @@ #define QXMLSCHEMA_H #include <QtCore/QSharedDataPointer> +#include <QtCore/QUrl> #include <QtXmlPatterns/QXmlNamePool> QT_BEGIN_HEADER @@ -37,9 +38,9 @@ class Q_XMLPATTERNS_EXPORT 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 load(const QUrl &source); + bool load(QIODevice *source, const QUrl &documentUri = QUrl()); + bool load(const QByteArray &data, const QUrl &documentUri = QUrl()); bool isValid() const; @@ -49,8 +50,8 @@ class Q_XMLPATTERNS_EXPORT QXmlSchema void setMessageHandler(QAbstractMessageHandler *handler); QAbstractMessageHandler *messageHandler() const; - void setUriResolver(QAbstractUriResolver *resolver); - QAbstractUriResolver *uriResolver() const; + void setUriResolver(const QAbstractUriResolver *resolver); + const QAbstractUriResolver *uriResolver() const; void setNetworkAccessManager(QNetworkAccessManager *networkmanager); QNetworkAccessManager *networkAccessManager() const; diff --git a/src/xmlpatterns/api/qxmlschema_p.cpp b/src/xmlpatterns/api/qxmlschema_p.cpp index ebcccee..21dc04a 100644 --- a/src/xmlpatterns/api/qxmlschema_p.cpp +++ b/src/xmlpatterns/api/qxmlschema_p.cpp @@ -61,7 +61,7 @@ QXmlSchemaPrivate::QXmlSchemaPrivate(const QXmlSchemaPrivate &other) void QXmlSchemaPrivate::load(const QUrl &source, const QString &targetNamespace) { - m_documentUri = source; + m_documentUri = QPatternist::XPathHelper::normalizeQueryURI(source); m_schemaContext->setMessageHandler(messageHandler()); m_schemaContext->setUriResolver(uriResolver()); @@ -98,7 +98,7 @@ void QXmlSchemaPrivate::load(QIODevice *source, const QUrl &documentUri, const Q return; } - m_documentUri = documentUri; + m_documentUri = QPatternist::XPathHelper::normalizeQueryURI(documentUri); m_schemaContext->setMessageHandler(messageHandler()); m_schemaContext->setUriResolver(uriResolver()); m_schemaContext->setNetworkAccessManager(networkAccessManager()); @@ -145,12 +145,12 @@ QAbstractMessageHandler *QXmlSchemaPrivate::messageHandler() const return m_messageHandler.data()->value; } -void QXmlSchemaPrivate::setUriResolver(QAbstractUriResolver *resolver) +void QXmlSchemaPrivate::setUriResolver(const QAbstractUriResolver *resolver) { m_uriResolver = resolver; } -QAbstractUriResolver *QXmlSchemaPrivate::uriResolver() const +const QAbstractUriResolver *QXmlSchemaPrivate::uriResolver() const { return m_uriResolver; } diff --git a/src/xmlpatterns/api/qxmlschema_p.h b/src/xmlpatterns/api/qxmlschema_p.h index e625f1e..efba256 100644 --- a/src/xmlpatterns/api/qxmlschema_p.h +++ b/src/xmlpatterns/api/qxmlschema_p.h @@ -54,14 +54,14 @@ class QXmlSchemaPrivate : public QSharedData QUrl documentUri() const; void setMessageHandler(QAbstractMessageHandler *handler); QAbstractMessageHandler *messageHandler() const; - void setUriResolver(QAbstractUriResolver *resolver); - QAbstractUriResolver *uriResolver() const; + void setUriResolver(const QAbstractUriResolver *resolver); + const QAbstractUriResolver *uriResolver() const; void setNetworkAccessManager(QNetworkAccessManager *networkmanager); QNetworkAccessManager *networkAccessManager() const; QXmlNamePool m_namePool; QAbstractMessageHandler* m_userMessageHandler; - QAbstractUriResolver* m_uriResolver; + const QAbstractUriResolver* m_uriResolver; QNetworkAccessManager* m_userNetworkAccessManager; QPatternist::ReferenceCountedValue<QAbstractMessageHandler>::Ptr m_messageHandler; QPatternist::ReferenceCountedValue<QNetworkAccessManager>::Ptr m_networkAccessManager; diff --git a/src/xmlpatterns/api/qxmlschemavalidator.cpp b/src/xmlpatterns/api/qxmlschemavalidator.cpp index aa80537..fcde49c 100644 --- a/src/xmlpatterns/api/qxmlschemavalidator.cpp +++ b/src/xmlpatterns/api/qxmlschemavalidator.cpp @@ -27,7 +27,7 @@ \brief The QXmlSchemaValidator class validates XML instance documents against a W3C XML Schema. \reentrant - \since 4.X + \since 4.6 \ingroup xml-tools The QXmlSchemaValidator class loads, parses an XML instance document and validates it @@ -35,6 +35,16 @@ */ /*! + Constructs a schema validator. + The schema used for validation must be referenced in the XML instance document + via the xsi:schemaLocation attribute. + */ +QXmlSchemaValidator::QXmlSchemaValidator() + : d(new QXmlSchemaValidatorPrivate(QXmlSchema())) +{ +} + +/*! Constructs a schema validator that will use \a schema for validation. */ QXmlSchemaValidator::QXmlSchemaValidator(const QXmlSchema &schema) @@ -65,7 +75,7 @@ void QXmlSchemaValidator::setSchema(const QXmlSchema &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) +bool QXmlSchemaValidator::validate(const QByteArray &data, const QUrl &documentUri) const { QByteArray localData(data); @@ -81,7 +91,7 @@ bool QXmlSchemaValidator::validate(const QByteArray &data, const QUrl &documentU Returns \c true if the XML instance document is valid according the schema, \c false otherwise. */ -bool QXmlSchemaValidator::validate(const QUrl &source) +bool QXmlSchemaValidator::validate(const QUrl &source) const { d->m_context->setMessageHandler(messageHandler()); d->m_context->setUriResolver(uriResolver()); @@ -102,7 +112,7 @@ bool QXmlSchemaValidator::validate(const QUrl &source) Returns \c true if the XML instance document is valid according the schema, \c false otherwise. */ -bool QXmlSchemaValidator::validate(QIODevice *source, const QUrl &documentUri) +bool QXmlSchemaValidator::validate(QIODevice *source, const QUrl &documentUri) const { if (!source) { qWarning("A null QIODevice pointer cannot be passed."); @@ -114,6 +124,8 @@ bool QXmlSchemaValidator::validate(QIODevice *source, const QUrl &documentUri) return false; } + const QUrl normalizedUri = QPatternist::XPathHelper::normalizeQueryURI(documentUri); + d->m_context->setMessageHandler(messageHandler()); d->m_context->setUriResolver(uriResolver()); d->m_context->setNetworkAccessManager(networkAccessManager()); @@ -125,7 +137,7 @@ bool QXmlSchemaValidator::validate(QIODevice *source, const QUrl &documentUri) QPatternist::Item item; try { - item = loader.openDocument(source, documentUri, d->m_context); + item = loader.openDocument(source, normalizedUri, d->m_context); } catch (QPatternist::Exception exception) { return false; } @@ -135,7 +147,7 @@ bool QXmlSchemaValidator::validate(QIODevice *source, const QUrl &documentUri) QPatternist::XsdValidatedXmlNodeModel *validatedModel = new QPatternist::XsdValidatedXmlNodeModel(model); - QPatternist::XsdValidatingInstanceReader reader(validatedModel, documentUri, d->m_context); + QPatternist::XsdValidatingInstanceReader reader(validatedModel, normalizedUri, d->m_context); if (d->m_schema) reader.addSchema(d->m_schema, d->m_schemaDocumentUri); try { @@ -158,6 +170,14 @@ QXmlNamePool QXmlSchemaValidator::namePool() const } /*! + Returns the schema that is used for validation. + */ +QXmlSchema QXmlSchemaValidator::schema() const +{ + return d->m_originalSchema; +} + +/*! 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 @@ -215,14 +235,14 @@ QAbstractMessageHandler *QXmlSchemaValidator::messageHandler() const \sa uriResolver() */ -void QXmlSchemaValidator::setUriResolver(QAbstractUriResolver *resolver) +void QXmlSchemaValidator::setUriResolver(const 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. + QtXmlPatterns will use the URIs in instance documents 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 @@ -234,7 +254,7 @@ void QXmlSchemaValidator::setUriResolver(QAbstractUriResolver *resolver) \sa setUriResolver() */ -QAbstractUriResolver *QXmlSchemaValidator::uriResolver() const +const QAbstractUriResolver *QXmlSchemaValidator::uriResolver() const { return d->m_uriResolver; } diff --git a/src/xmlpatterns/api/qxmlschemavalidator.h b/src/xmlpatterns/api/qxmlschemavalidator.h index e643995..c82c522 100644 --- a/src/xmlpatterns/api/qxmlschemavalidator.h +++ b/src/xmlpatterns/api/qxmlschemavalidator.h @@ -12,6 +12,7 @@ #ifndef QXMLSCHEMAVALIDATOR_H #define QXMLSCHEMAVALIDATOR_H +#include <QtCore/QUrl> #include <QtXmlPatterns/QXmlNamePool> QT_BEGIN_HEADER @@ -31,22 +32,24 @@ class QXmlSchemaValidatorPrivate; class Q_XMLPATTERNS_EXPORT QXmlSchemaValidator { public: + QXmlSchemaValidator(); 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); + bool validate(const QUrl &source) const; + bool validate(QIODevice *source, const QUrl &documentUri = QUrl()) const; + bool validate(const QByteArray &data, const QUrl &documentUri = QUrl()) const; QXmlNamePool namePool() const; + QXmlSchema schema() const; void setMessageHandler(QAbstractMessageHandler *handler); QAbstractMessageHandler *messageHandler() const; - void setUriResolver(QAbstractUriResolver *resolver); - QAbstractUriResolver *uriResolver() const; + void setUriResolver(const QAbstractUriResolver *resolver); + const QAbstractUriResolver *uriResolver() const; void setNetworkAccessManager(QNetworkAccessManager *networkmanager); QNetworkAccessManager *networkAccessManager() const; diff --git a/src/xmlpatterns/api/qxmlschemavalidator_p.h b/src/xmlpatterns/api/qxmlschemavalidator_p.h index 0990f73..9910f6e 100644 --- a/src/xmlpatterns/api/qxmlschemavalidator_p.h +++ b/src/xmlpatterns/api/qxmlschemavalidator_p.h @@ -77,15 +77,18 @@ public: 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; + + m_originalSchema = schema; } QXmlNamePool m_namePool; QAbstractMessageHandler* m_userMessageHandler; - QAbstractUriResolver* m_uriResolver; + const QAbstractUriResolver* m_uriResolver; QNetworkAccessManager* m_userNetworkAccessManager; QPatternist::ReferenceCountedValue<QAbstractMessageHandler>::Ptr m_messageHandler; QPatternist::ReferenceCountedValue<QNetworkAccessManager>::Ptr m_networkAccessManager; + QXmlSchema m_originalSchema; QPatternist::XsdSchemaContext::Ptr m_context; QPatternist::XsdSchema::Ptr m_schema; QUrl m_schemaDocumentUri; diff --git a/src/xmlpatterns/schema/qnamespacesupport.cpp b/src/xmlpatterns/schema/qnamespacesupport.cpp index 00698d6..349f451 100644 --- a/src/xmlpatterns/schema/qnamespacesupport.cpp +++ b/src/xmlpatterns/schema/qnamespacesupport.cpp @@ -33,9 +33,7 @@ NamespaceSupport::NamespaceSupport(const NamePool::Ptr &namePool) : m_namePool(namePool) { // the XML namespace - const QXmlName binding = namePool->allocateBinding(QLatin1String("xml"), - QLatin1String("http://www.w3.org/XML/1998/namespace")); - m_ns.insert(binding.prefix(), binding.namespaceURI()); + m_ns.insert(StandardPrefixes::xml, StandardNamespaces::xml); } void NamespaceSupport::setPrefix(const QXmlName::PrefixCode prefixCode, const QXmlName::NamespaceCode namespaceCode) diff --git a/src/xmlpatterns/schema/qxsdparticlechecker.cpp b/src/xmlpatterns/schema/qxsdparticlechecker.cpp index 1bdef00..7a09f8a 100644 --- a/src/xmlpatterns/schema/qxsdparticlechecker.cpp +++ b/src/xmlpatterns/schema/qxsdparticlechecker.cpp @@ -180,9 +180,9 @@ static bool derivedTermValid(const XsdTerm::Ptr &baseTerm, const XsdTerm::Ptr &d // check that the constraints of the derived element are more strict then the constraints of the base element const XsdElement::BlockingConstraints baseConstraints = element->disallowedSubstitutions(); const XsdElement::BlockingConstraints derivedConstraints = derivedElement->disallowedSubstitutions(); - if ((baseConstraints & XsdElement::RestrictionConstraint) && !(derivedConstraints & XsdElement::RestrictionConstraint) || - (baseConstraints & XsdElement::ExtensionConstraint) && !(derivedConstraints & XsdElement::ExtensionConstraint) || - (baseConstraints & XsdElement::SubstitutionConstraint) && !(derivedConstraints & XsdElement::SubstitutionConstraint)) { + if (((baseConstraints & XsdElement::RestrictionConstraint) && !(derivedConstraints & XsdElement::RestrictionConstraint)) || + ((baseConstraints & XsdElement::ExtensionConstraint) && !(derivedConstraints & XsdElement::ExtensionConstraint)) || + ((baseConstraints & XsdElement::SubstitutionConstraint) && !(derivedConstraints & XsdElement::SubstitutionConstraint))) { errorMsg = QtXmlPatterns::tr("block constraints of derived element %1 must not be more weaker than in the base element").arg(formatKeyword(derivedElement->displayName(namePool))); return false; } diff --git a/src/xmlpatterns/schema/qxsdschemacontext.cpp b/src/xmlpatterns/schema/qxsdschemacontext.cpp index 57736bd..65b2e52 100644 --- a/src/xmlpatterns/schema/qxsdschemacontext.cpp +++ b/src/xmlpatterns/schema/qxsdschemacontext.cpp @@ -67,7 +67,7 @@ QSourceLocation XsdSchemaContext::locationFor(const SourceLocationReflection *co return QSourceLocation(); } -void XsdSchemaContext::setUriResolver(QAbstractUriResolver *uriResolver) +void XsdSchemaContext::setUriResolver(const QAbstractUriResolver *uriResolver) { m_uriResolver = uriResolver; } diff --git a/src/xmlpatterns/schema/qxsdschemacontext_p.h b/src/xmlpatterns/schema/qxsdschemacontext_p.h index cf52028..c3a9f15 100644 --- a/src/xmlpatterns/schema/qxsdschemacontext_p.h +++ b/src/xmlpatterns/schema/qxsdschemacontext_p.h @@ -115,7 +115,7 @@ namespace QPatternist * Sets the uri @p resolver that is used for resolving URIs in the * schema parser. */ - void setUriResolver(QAbstractUriResolver *resolver); + void setUriResolver(const QAbstractUriResolver *resolver); /** * Returns the uri resolver that is used for resolving URIs in the @@ -145,7 +145,7 @@ namespace QPatternist NamePool::Ptr m_namePool; QNetworkAccessManager* m_networkAccessManager; QUrl m_baseURI; - QAbstractUriResolver* m_uriResolver; + const QAbstractUriResolver* m_uriResolver; QAbstractMessageHandler* m_messageHandler; }; } diff --git a/src/xmlpatterns/schema/qxsdschemadebugger_p.h b/src/xmlpatterns/schema/qxsdschemadebugger_p.h index 8c12f0f..8966963 100644 --- a/src/xmlpatterns/schema/qxsdschemadebugger_p.h +++ b/src/xmlpatterns/schema/qxsdschemadebugger_p.h @@ -85,7 +85,7 @@ namespace QPatternist void dumpSchema(const XsdSchema::Ptr &schema); private: - NamePool::Ptr m_namePool; + const NamePool::Ptr m_namePool; }; } diff --git a/src/xmlpatterns/schema/qxsdschemahelper.cpp b/src/xmlpatterns/schema/qxsdschemahelper.cpp index 752af89..ff169f7 100644 --- a/src/xmlpatterns/schema/qxsdschemahelper.cpp +++ b/src/xmlpatterns/schema/qxsdschemahelper.cpp @@ -409,7 +409,7 @@ bool XsdSchemaHelper::isValidlySubstitutable(const SchemaType::Ptr &type, const return false; } -bool XsdSchemaHelper::isSimpleDerivationOk(const SchemaType::Ptr &derivedType, const SchemaType::Ptr baseType, const SchemaType::DerivationConstraints &constraints) +bool XsdSchemaHelper::isSimpleDerivationOk(const SchemaType::Ptr &derivedType, const SchemaType::Ptr &baseType, const SchemaType::DerivationConstraints &constraints) { // @see http://www.w3.org/TR/xmlschema11-1/#cos-st-derived-ok @@ -453,7 +453,7 @@ bool XsdSchemaHelper::isSimpleDerivationOk(const SchemaType::Ptr &derivedType, c return false; } -bool XsdSchemaHelper::isComplexDerivationOk(const SchemaType::Ptr &derivedType, const SchemaType::Ptr baseType, const SchemaType::DerivationConstraints &constraints) +bool XsdSchemaHelper::isComplexDerivationOk(const SchemaType::Ptr &derivedType, const SchemaType::Ptr &baseType, const SchemaType::DerivationConstraints &constraints) { if (!derivedType) return false; diff --git a/src/xmlpatterns/schema/qxsdschemahelper_p.h b/src/xmlpatterns/schema/qxsdschemahelper_p.h index 1722b4c..918664e 100644 --- a/src/xmlpatterns/schema/qxsdschemahelper_p.h +++ b/src/xmlpatterns/schema/qxsdschemahelper_p.h @@ -55,12 +55,15 @@ namespace QPatternist /** * Checks whether the given @p nameSpace is allowed by the given namespace @p constraint. */ - static bool wildcardAllowsNamespaceName(const QString &nameSpace, const XsdWildcard::NamespaceConstraint::Ptr &constraint); + static bool wildcardAllowsNamespaceName(const QString &nameSpace, + const XsdWildcard::NamespaceConstraint::Ptr &constraint); /** * Checks whether the given @p name is allowed by the namespace constraint of the given @p wildcard. */ - static bool wildcardAllowsExpandedName(const QXmlName &name, const XsdWildcard::Ptr &wildcard, const NamePool::Ptr &namePool); + static bool wildcardAllowsExpandedName(const QXmlName &name, + const XsdWildcard::Ptr &wildcard, + const NamePool::Ptr &namePool); /** * Checks whether the @p wildcard is a subset of @p otherWildcard. @@ -75,25 +78,32 @@ namespace QPatternist /** * Returns the intersection of the given @p wildcard and @p otherWildcard. */ - static XsdWildcard::Ptr wildcardIntersection(const XsdWildcard::Ptr &wildcard, const XsdWildcard::Ptr &otherWildcard); + static XsdWildcard::Ptr wildcardIntersection(const XsdWildcard::Ptr &wildcard, + const XsdWildcard::Ptr &otherWildcard); /** * Returns whether the given @p type is validly substitutable for an @p otherType * under the given @p constraints. */ - static bool isValidlySubstitutable(const SchemaType::Ptr &type, const SchemaType::Ptr &otherType, const SchemaType::DerivationConstraints &constraints); + static bool isValidlySubstitutable(const SchemaType::Ptr &type, + const SchemaType::Ptr &otherType, + const SchemaType::DerivationConstraints &constraints); /** * Returns whether the simple @p derivedType can be derived from the simple @p baseType * under the given @p constraints. */ - static bool isSimpleDerivationOk(const SchemaType::Ptr &derivedType, const SchemaType::Ptr baseType, const SchemaType::DerivationConstraints &constraints); + static bool isSimpleDerivationOk(const SchemaType::Ptr &derivedType, + const SchemaType::Ptr &baseType, + const SchemaType::DerivationConstraints &constraints); /** * Returns whether the complex @p derivedType can be derived from the complex @p baseType * under the given @p constraints. */ - static bool isComplexDerivationOk(const SchemaType::Ptr &derivedType, const SchemaType::Ptr baseType, const SchemaType::DerivationConstraints &constraints); + static bool isComplexDerivationOk(const SchemaType::Ptr &derivedType, + const SchemaType::Ptr &baseType, + const SchemaType::DerivationConstraints &constraints); /** * This method takes the two string based operands @p operand1 and @p operand2 and converts them to instances of type @p type. @@ -111,41 +121,62 @@ namespace QPatternist * Returns whether the process content property of the @p derivedWildcard is valid * according to the process content property of its @p baseWildcard. */ - static bool checkWildcardProcessContents(const XsdWildcard::Ptr &baseWildcard, const XsdWildcard::Ptr &derivedWildcard); + static bool checkWildcardProcessContents(const XsdWildcard::Ptr &baseWildcard, + const XsdWildcard::Ptr &derivedWildcard); /** * Checks whether @[ member is a member of the substitution group with the given @p head. */ - static bool foundSubstitutionGroupTransitive(const XsdElement::Ptr &head, const XsdElement::Ptr &member, QSet<XsdElement::Ptr> &visitedElements); + static bool foundSubstitutionGroupTransitive(const XsdElement::Ptr &head, + const XsdElement::Ptr &member, + QSet<XsdElement::Ptr> &visitedElements); /** * A helper method that iterates over the type hierarchy from @p memberType up to @p headType and collects all * @p derivationSet and @p blockSet constraints that exists on the way there. */ - static void foundSubstitutionGroupTypeInheritance(const SchemaType::Ptr &headType, const SchemaType::Ptr &memberType, - QSet<SchemaType::DerivationMethod> &derivationSet, NamedSchemaComponent::BlockingConstraints &blockSet); + static void foundSubstitutionGroupTypeInheritance(const SchemaType::Ptr &headType, + const SchemaType::Ptr &memberType, + QSet<SchemaType::DerivationMethod> &derivationSet, + NamedSchemaComponent::BlockingConstraints &blockSet); /** * Checks if the @p member is transitive to @p head. */ - static bool substitutionGroupOkTransitive(const XsdElement::Ptr &head, const XsdElement::Ptr &member, const NamePool::Ptr &namePool); + static bool substitutionGroupOkTransitive(const XsdElement::Ptr &head, + const XsdElement::Ptr &member, + const NamePool::Ptr &namePool); /** * Checks if @p derivedAttributeGroup is a valid restriction for @p attributeGroup. */ - static bool isValidAttributeGroupRestriction(const XsdAttributeGroup::Ptr &derivedAttributeGroup, const XsdAttributeGroup::Ptr &attributeGroup, const XsdSchemaContext::Ptr &context, QString &errorMsg); + static bool isValidAttributeGroupRestriction(const XsdAttributeGroup::Ptr &derivedAttributeGroup, + const XsdAttributeGroup::Ptr &attributeGroup, + const XsdSchemaContext::Ptr &context, + QString &errorMsg); /** * Checks if @p derivedAttributeUses are a valid restriction for @p attributeUses. */ - static bool isValidAttributeUsesRestriction(const XsdAttributeUse::List &derivedAttributeUses, const XsdAttributeUse::List &attributeUses, - const XsdWildcard::Ptr &derivedWildcard, const XsdWildcard::Ptr &wildcard, const XsdSchemaContext::Ptr &context, QString &errorMsg); + static bool isValidAttributeUsesRestriction(const XsdAttributeUse::List &derivedAttributeUses, + const XsdAttributeUse::List &attributeUses, + const XsdWildcard::Ptr &derivedWildcard, + const XsdWildcard::Ptr &wildcard, + const XsdSchemaContext::Ptr &context, + QString &errorMsg); /** * Checks if @p derivedAttributeUses are a valid extension for @p attributeUses. */ - static bool isValidAttributeUsesExtension(const XsdAttributeUse::List &derivedAttributeUses, const XsdAttributeUse::List &attributeUses, - const XsdWildcard::Ptr &derivedWildcard, const XsdWildcard::Ptr &wildcard, const XsdSchemaContext::Ptr &context, QString &errorMsg); + static bool isValidAttributeUsesExtension(const XsdAttributeUse::List &derivedAttributeUses, + const XsdAttributeUse::List &attributeUses, + const XsdWildcard::Ptr &derivedWildcard, + const XsdWildcard::Ptr &wildcard, + const XsdSchemaContext::Ptr &context, + QString &errorMsg); + + private: + Q_DISABLE_COPY(XsdSchemaHelper) }; } diff --git a/src/xmlpatterns/schema/qxsdschemaparser.cpp b/src/xmlpatterns/schema/qxsdschemaparser.cpp index 9f1e75d..cabc12e 100644 --- a/src/xmlpatterns/schema/qxsdschemaparser.cpp +++ b/src/xmlpatterns/schema/qxsdschemaparser.cpp @@ -5,6 +5,7 @@ #include "qacceltreeresourceloader_p.h" #include "qautoptr_p.h" #include "qboolean_p.h" +#include "qcommonnamespaces_p.h" #include "qderivedinteger_p.h" #include "qderivedstring_p.h" #include "qqnamevalue_p.h" @@ -119,12 +120,28 @@ class TagValidationHandler void validate(XsdSchemaToken::NodeName token) { if (token == XsdSchemaToken::NoKeyword) { - m_parser->error(QtXmlPatterns::tr("can not process unknown element %1").arg(formatElement(m_parser->name().toString()))); + const QList<XsdSchemaToken::NodeName> tokens = m_machine.possibleTransitions(); + + QStringList elementNames; + for (int i = 0; i < tokens.count(); ++i) + elementNames.append(formatElement(XsdSchemaToken::toString(tokens.at(i)))); + + m_parser->error(QtXmlPatterns::tr("can not process unknown element %1, expected elements are: %2") + .arg(formatElement(m_parser->name().toString())) + .arg(elementNames.join(QLatin1String(", ")))); return; } if (!m_machine.proceed(token)) { - m_parser->error(QtXmlPatterns::tr("element %1 is not allowed in this scope").arg(formatElement(XsdSchemaToken::toString(token)))); + const QList<XsdSchemaToken::NodeName> tokens = m_machine.possibleTransitions(); + + QStringList elementNames; + for (int i = 0; i < tokens.count(); ++i) + elementNames.append(formatElement(XsdSchemaToken::toString(tokens.at(i)))); + + m_parser->error(QtXmlPatterns::tr("element %1 is not allowed in this scope, possible elements are: %2") + .arg(formatElement(XsdSchemaToken::toString(token))) + .arg(elementNames.join(QLatin1String(", ")))); return; } } @@ -132,7 +149,14 @@ class TagValidationHandler void finalize() const { if (!m_machine.inEndState()) { - m_parser->error(QtXmlPatterns::tr("child element is missing in that scope")); + const QList<XsdSchemaToken::NodeName> tokens = m_machine.possibleTransitions(); + + QStringList elementNames; + for (int i = 0; i < tokens.count(); ++i) + elementNames.append(formatElement(XsdSchemaToken::toString(tokens.at(i)))); + + m_parser->error(QtXmlPatterns::tr("child element is missing in that scope, possible child elements are: %1") + .arg(elementNames.join(QLatin1String(", ")))); } } @@ -425,8 +449,8 @@ void XsdSchemaParser::parseSchema(ParserType parserType) const QString version = readAttribute(QString::fromLatin1("version")); } - if (hasAttribute(QString::fromLatin1("http://www.w3.org/XML/1998/namespace"), QString::fromLatin1("lang"))) { - const QString value = readAttribute(QString::fromLatin1("lang"), QString::fromLatin1("http://www.w3.org/XML/1998/namespace")); + if (hasAttribute(CommonNamespaces::XML, QString::fromLatin1("lang"))) { + const QString value = readAttribute(QString::fromLatin1("lang"), CommonNamespaces::XML); const QRegExp exp(QString::fromLatin1("[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*")); if (!exp.exactMatch(value)) { @@ -750,7 +774,7 @@ void XsdSchemaParser::parseRedefine() if (url.isRelative()) { Q_ASSERT(m_documentURI.isValid()); - url = m_documentURI.resolved(url); + url = m_documentURI.resolved(url); } // we parse the schema given in the redefine tag into its own context @@ -1176,8 +1200,8 @@ XsdDocumentation::Ptr XsdSchemaParser::parseDocumentation() } } - if (hasAttribute(QString::fromLatin1("http://www.w3.org/XML/1998/namespace"), QString::fromLatin1("lang"))) { - const QString value = readAttribute(QString::fromLatin1("lang"), QString::fromLatin1("http://www.w3.org/XML/1998/namespace")); + if (hasAttribute(CommonNamespaces::XML, QString::fromLatin1("lang"))) { + const QString value = readAttribute(QString::fromLatin1("lang"), CommonNamespaces::XML); const QRegExp exp(QString::fromLatin1("[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*")); if (!exp.exactMatch(value)) { @@ -3948,7 +3972,7 @@ XsdAttribute::Ptr XsdSchemaParser::parseGlobalAttribute() error(QtXmlPatterns::tr("content of %1 attribute of %2 element must not be from namespace %3") .arg(formatAttribute("name")) .arg(formatElement("attribute")) - .arg(formatURI(QLatin1String("http://www.w3.org/2001/XMLSchema-instance")))); + .arg(formatURI(CommonNamespaces::XSI))); return attribute; } if (m_namePool->stringForLocalName(objectName.localName()) == QString::fromLatin1("xmlns")) { @@ -4170,7 +4194,7 @@ XsdAttributeUse::Ptr XsdSchemaParser::parseLocalAttribute(const NamedSchemaCompo error(QtXmlPatterns::tr("content of %1 attribute of %2 element must not be from namespace %3") .arg(formatAttribute("name")) .arg(formatElement("attribute")) - .arg(formatURI(QLatin1String("http://www.w3.org/2001/XMLSchema-instance")))); + .arg(formatURI(CommonNamespaces::XSI))); return attributeUse; } if (m_namePool->stringForLocalName(objectName.localName()) == QString::fromLatin1("xmlns")) { @@ -5858,7 +5882,7 @@ QString XsdSchemaParser::readXPathAttribute(const QString &attributeName, XPathT QXmlNamePool namePool(m_namePool.data()); - QXmlQuery::QueryLanguage language; + QXmlQuery::QueryLanguage language = QXmlQuery::XPath20; switch (type) { case XPath20: language = QXmlQuery::XPath20; break; case XPathSelector: language = QXmlQuery::XmlSchema11IdentityConstraintSelector; break; diff --git a/src/xmlpatterns/schema/qxsdstatemachine.cpp b/src/xmlpatterns/schema/qxsdstatemachine.cpp index e40e55b..4f36f22 100644 --- a/src/xmlpatterns/schema/qxsdstatemachine.cpp +++ b/src/xmlpatterns/schema/qxsdstatemachine.cpp @@ -114,6 +114,20 @@ bool XsdStateMachine<TransitionType>::proceed(TransitionType transition) } template <typename TransitionType> +QList<TransitionType> XsdStateMachine<TransitionType>::possibleTransitions() const +{ + // check that we are not in an invalid state + if (!m_transitions.contains(m_currentState)) { + return QList<TransitionType>(); + } + + // fetch the transition entry for the current state + const QHash<TransitionType, QVector<StateId> > &entry = m_transitions[m_currentState]; + + return entry.keys(); +} + +template <typename TransitionType> template <typename InputType> bool XsdStateMachine<TransitionType>::proceed(InputType input) { @@ -259,7 +273,7 @@ typename XsdStateMachine<TransitionType>::StateId XsdStateMachine<TransitionType } // check if the NFA state set contains a Start or End - // state, in that case our new DFA state will be a + // state, in that case our new DFA state will be a // Start or End state as well StateType type = InternalState; QSetIterator<StateId> it(nfaState); diff --git a/src/xmlpatterns/schema/qxsdstatemachine_p.h b/src/xmlpatterns/schema/qxsdstatemachine_p.h index 7988335..f0cf99d 100644 --- a/src/xmlpatterns/schema/qxsdstatemachine_p.h +++ b/src/xmlpatterns/schema/qxsdstatemachine_p.h @@ -113,6 +113,12 @@ namespace QPatternist bool proceed(TransitionType transition); /** + * Returns the list of transitions that are reachable from the current + * state. + */ + QList<TransitionType> possibleTransitions() const; + + /** * Continues execution of the machine with the given @p input. * * @note To use this method, inputEqualsTransition must be implemented diff --git a/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel.cpp b/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel.cpp index 8e1645a..33bca4e 100644 --- a/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel.cpp +++ b/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel.cpp @@ -20,7 +20,7 @@ QT_BEGIN_NAMESPACE using namespace QPatternist; XsdValidatedXmlNodeModel::XsdValidatedXmlNodeModel(const QAbstractXmlNodeModel *model) - : m_internalModel(const_cast<QAbstractXmlNodeModel*>(model)) + : m_internalModel(model) { } diff --git a/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel_p.h b/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel_p.h index 579f41a..d52e369 100644 --- a/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel_p.h +++ b/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel_p.h @@ -134,11 +134,11 @@ namespace QPatternist virtual QVector<QXmlNodeModelIndex> attributes(const QXmlNodeModelIndex &element) const; private: - QAbstractXmlNodeModel::Ptr m_internalModel; - QHash<QXmlNodeModelIndex, XsdElement::Ptr> m_assignedElements; - QHash<QXmlNodeModelIndex, XsdAttribute::Ptr> m_assignedAttributes; - QHash<QXmlNodeModelIndex, SchemaType::Ptr> m_assignedTypes; - QHash<QString, QSet<NamedSchemaComponent::Ptr> > m_idIdRefBindings; + QExplicitlySharedDataPointer<const QAbstractXmlNodeModel> m_internalModel; + QHash<QXmlNodeModelIndex, XsdElement::Ptr> m_assignedElements; + QHash<QXmlNodeModelIndex, XsdAttribute::Ptr> m_assignedAttributes; + QHash<QXmlNodeModelIndex, SchemaType::Ptr> m_assignedTypes; + QHash<QString, QSet<NamedSchemaComponent::Ptr> > m_idIdRefBindings; }; } diff --git a/src/xmlpatterns/schema/qxsdvalidatinginstancereader.cpp b/src/xmlpatterns/schema/qxsdvalidatinginstancereader.cpp index 12fc477..8cb34d4 100644 --- a/src/xmlpatterns/schema/qxsdvalidatinginstancereader.cpp +++ b/src/xmlpatterns/schema/qxsdvalidatinginstancereader.cpp @@ -15,6 +15,7 @@ #include "qacceltreeresourceloader_p.h" #include "qbase64binary_p.h" #include "qboolean_p.h" +#include "qcommonnamespaces_p.h" #include "qderivedinteger_p.h" #include "qduration_p.h" #include "qgenericstaticcontext_p.h" @@ -64,14 +65,14 @@ namespace QPatternist } } -XsdValidatingInstanceReader::XsdValidatingInstanceReader(const XsdValidatedXmlNodeModel *model, const QUrl &documentUri, const XsdSchemaContext::Ptr &context) +XsdValidatingInstanceReader::XsdValidatingInstanceReader(XsdValidatedXmlNodeModel *model, const QUrl &documentUri, const XsdSchemaContext::Ptr &context) : XsdInstanceReader(model, context) - , m_model(const_cast<XsdValidatedXmlNodeModel*>(model)) + , m_model(model) , m_namePool(m_context->namePool()) - , m_xsiNilName(m_namePool->allocateQName(QLatin1String("http://www.w3.org/2001/XMLSchema-instance"), QLatin1String("nil"))) - , m_xsiTypeName(m_namePool->allocateQName(QLatin1String("http://www.w3.org/2001/XMLSchema-instance"), QLatin1String("type"))) - , m_xsiSchemaLocationName(m_namePool->allocateQName(QLatin1String("http://www.w3.org/2001/XMLSchema-instance"), QLatin1String("schemaLocation"))) - , m_xsiNoNamespaceSchemaLocationName(m_namePool->allocateQName(QLatin1String("http://www.w3.org/2001/XMLSchema-instance"), QLatin1String("noNamespaceSchemaLocation"))) + , m_xsiNilName(m_namePool->allocateQName(CommonNamespaces::XSI, QLatin1String("nil"))) + , m_xsiTypeName(m_namePool->allocateQName(CommonNamespaces::XSI, QLatin1String("type"))) + , m_xsiSchemaLocationName(m_namePool->allocateQName(CommonNamespaces::XSI, QLatin1String("schemaLocation"))) + , m_xsiNoNamespaceSchemaLocationName(m_namePool->allocateQName(CommonNamespaces::XSI, QLatin1String("noNamespaceSchemaLocation"))) , m_documentUri(documentUri) { m_idRefsType = m_context->schemaTypeFactory()->createSchemaType(m_namePool->allocateQName(CommonNamespaces::WXS, QLatin1String("IDREFS"))); @@ -152,7 +153,7 @@ bool XsdValidatingInstanceReader::read() void XsdValidatingInstanceReader::error(const QString &msg) const { - const_cast<XsdSchemaContext*>(m_context.data())->error(msg, XsdSchemaContext::XSDError, sourceLocation()); + m_context.data()->error(msg, XsdSchemaContext::XSDError, sourceLocation()); } bool XsdValidatingInstanceReader::loadSchema(const QString &targetNamespace, const QUrl &location) diff --git a/src/xmlpatterns/schema/qxsdvalidatinginstancereader_p.h b/src/xmlpatterns/schema/qxsdvalidatinginstancereader_p.h index 799ab44..28f3c3f 100644 --- a/src/xmlpatterns/schema/qxsdvalidatinginstancereader_p.h +++ b/src/xmlpatterns/schema/qxsdvalidatinginstancereader_p.h @@ -59,7 +59,7 @@ namespace QPatternist * @param documentUri The uri of the document the model is from. * @param context The context that is used to report errors etc. */ - XsdValidatingInstanceReader(const XsdValidatedXmlNodeModel *model, const QUrl &documentUri, const XsdSchemaContext::Ptr &context); + XsdValidatingInstanceReader(XsdValidatedXmlNodeModel *model, const QUrl &documentUri, const XsdSchemaContext::Ptr &context); /** * Adds a new @p schema to the pool of schemas that shall be used diff --git a/src/xmlpatterns/utils/qxpathhelper.cpp b/src/xmlpatterns/utils/qxpathhelper.cpp index 127e21f..5b32906 100644 --- a/src/xmlpatterns/utils/qxpathhelper.cpp +++ b/src/xmlpatterns/utils/qxpathhelper.cpp @@ -125,4 +125,16 @@ ItemType::Ptr XPathHelper::typeFromKind(const QXmlNodeModelIndex::NodeKind nodeK } } +QUrl XPathHelper::normalizeQueryURI(const QUrl &uri) +{ + Q_ASSERT_X(uri.isEmpty() || uri.isValid(), Q_FUNC_INFO, + "The URI passed to QXmlQuery::setQuery() must be valid or empty."); + if(uri.isEmpty()) + return QUrl::fromLocalFile(QCoreApplication::applicationFilePath()); + else if(uri.isRelative()) + return QUrl::fromLocalFile(QCoreApplication::applicationFilePath()).resolved(uri); + else + return uri; +} + QT_END_NAMESPACE diff --git a/src/xmlpatterns/utils/qxpathhelper_p.h b/src/xmlpatterns/utils/qxpathhelper_p.h index 7bf33e6..e36b8cb 100644 --- a/src/xmlpatterns/utils/qxpathhelper_p.h +++ b/src/xmlpatterns/utils/qxpathhelper_p.h @@ -128,6 +128,11 @@ namespace QPatternist static QPatternist::ItemTypePtr typeFromKind(const QXmlNodeModelIndex::NodeKind nodeKind); /** + * Normalizes an @p uri by resolving it to the application directory if empty. + */ + static QUrl normalizeQueryURI(const QUrl &uri); + + /** * @short Determines whether @p consists only of whitespace. Characters * considered whitespace are the ones for which QChar::isSpace() returns @c true for. * diff --git a/tests/auto/patternistheaders/tst_patternistheaders.cpp b/tests/auto/patternistheaders/tst_patternistheaders.cpp index ba7623e..3352a58 100644 --- a/tests/auto/patternistheaders/tst_patternistheaders.cpp +++ b/tests/auto/patternistheaders/tst_patternistheaders.cpp @@ -94,6 +94,10 @@ void tst_PatternistHeaders::run() const #include <qxmlquery.h> #include <QXmlResultItems> #include <qxmlresultitems.h> +#include <QXmlSchema> +#include <qxmlschema.h> +#include <QXmlSchemaValidator> +#include <qxmlschemavalidator.h> #include <QXmlSerializer> #include <qxmlserializer.h> @@ -122,6 +126,10 @@ void tst_PatternistHeaders::run() const #include <QtXmlPatterns/qxmlquery.h> #include <QtXmlPatterns/QXmlResultItems> #include <QtXmlPatterns/qxmlresultitems.h> +#include <QtXmlPatterns/QXmlSchema> +#include <QtXmlPatterns/qxmlschema.h> +#include <QtXmlPatterns/QXmlSchemaValidator> +#include <QtXmlPatterns/qxmlschemavalidator.h> #include <QtXmlPatterns/QXmlSerializer> #include <QtXmlPatterns/qxmlserializer.h> diff --git a/tests/auto/qxmlschema/tst_qxmlschema.cpp b/tests/auto/qxmlschema/tst_qxmlschema.cpp index 64012c1..7fc59bb 100644 --- a/tests/auto/qxmlschema/tst_qxmlschema.cpp +++ b/tests/auto/qxmlschema/tst_qxmlschema.cpp @@ -15,33 +15,8 @@ #include <QXmlName> #include <QXmlSchema> -class DummyMessageHandler : public QAbstractMessageHandler -{ - public: - DummyMessageHandler(QObject *parent = 0) - : QAbstractMessageHandler(parent) - { - } - - protected: - virtual void handleMessage(QtMsgType, const QString&, const QUrl&, const QSourceLocation&) - { - } -}; - -class DummyUriResolver : public QAbstractUriResolver -{ - public: - DummyUriResolver(QObject *parent = 0) - : QAbstractUriResolver(parent) - { - } - - virtual QUrl resolve(const QUrl&, const QUrl&) const - { - return QUrl(); - } -}; +#include "../qabstracturiresolver/TestURIResolver.h" +#include "../qxmlquery/MessageSilencer.h" /*! \class tst_QXmlSchema @@ -59,6 +34,17 @@ private Q_SLOTS: void defaultConstructor() const; void copyConstructor() const; void constructorQXmlNamePool() const; + void copyMutationTest() const; + + void isValid() const; + void documentUri() const; + + void loadSchemaUrlSuccess() const; + void loadSchemaUrlFail() const; + void loadSchemaDeviceSuccess() const; + void loadSchemaDeviceFail() const; + void loadSchemaDataSuccess() const; + void loadSchemaDataFail() const; void networkAccessManagerSignature() const; void networkAccessManagerDefaultValue() const; @@ -134,6 +120,150 @@ void tst_QXmlSchema::constructorQXmlNamePool() const QCOMPARE(name.prefix(np2), QString::fromLatin1("prefix")); } +void tst_QXmlSchema::copyMutationTest() const +{ + QXmlSchema schema1; + QXmlSchema schema2(schema1); + + // check that everything is equal + QVERIFY(schema2.messageHandler() == schema1.messageHandler()); + QVERIFY(schema2.uriResolver() == schema1.uriResolver()); + QVERIFY(schema2.networkAccessManager() == schema1.networkAccessManager()); + + MessageSilencer handler; + const TestURIResolver resolver; + QNetworkAccessManager manager; + + // modify schema1 + schema1.setMessageHandler(&handler); + schema1.setUriResolver(&resolver); + schema1.setNetworkAccessManager(&manager); + + // check that schema2 is not effected by the modifications of schema1 + QVERIFY(schema2.messageHandler() != schema1.messageHandler()); + QVERIFY(schema2.uriResolver() != schema1.uriResolver()); + QVERIFY(schema2.networkAccessManager() != schema1.networkAccessManager()); + + // modify schema1 further + const QByteArray data( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<xsd:schema" + " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"" + " xmlns=\"http://www.qtsoftware.com/xmlschematest\"" + " targetNamespace=\"http://www.qtsoftware.com/xmlschematest\"" + " version=\"1.0\"" + " elementFormDefault=\"qualified\">" + "</xsd:schema>" ); + + const QUrl documentUri("http://www.qtsoftware.com/xmlschematest"); + schema1.load(data, documentUri); + + QVERIFY(schema2.isValid() != schema1.isValid()); +} + +void tst_QXmlSchema::isValid() const +{ + /* Check default value. */ + QXmlSchema schema; + QVERIFY(!schema.isValid()); +} + +void tst_QXmlSchema::documentUri() const +{ + const QByteArray data( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<xsd:schema" + " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"" + " xmlns=\"http://www.qtsoftware.com/xmlschematest\"" + " targetNamespace=\"http://www.qtsoftware.com/xmlschematest\"" + " version=\"1.0\"" + " elementFormDefault=\"qualified\">" + "</xsd:schema>" ); + + const QUrl documentUri("http://www.qtsoftware.com/xmlschematest"); + QXmlSchema schema; + schema.load(data, documentUri); + + QCOMPARE(documentUri, schema.documentUri()); +} + +void tst_QXmlSchema::loadSchemaUrlSuccess() const +{ +/** + TODO: put valid schema file on given url and enable test + const QUrl url("http://notavailable/"); + + QXmlSchema schema; + QVERIFY(!schema.load(url)); +*/ +} + +void tst_QXmlSchema::loadSchemaUrlFail() const +{ + const QUrl url("http://notavailable/"); + + QXmlSchema schema; + QVERIFY(!schema.load(url)); +} + +void tst_QXmlSchema::loadSchemaDeviceSuccess() const +{ + QByteArray data( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<xsd:schema" + " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"" + " xmlns=\"http://www.qtsoftware.com/xmlschematest\"" + " targetNamespace=\"http://www.qtsoftware.com/xmlschematest\"" + " version=\"1.0\"" + " elementFormDefault=\"qualified\">" + "</xsd:schema>" ); + + QBuffer buffer(&data); + buffer.open(QIODevice::ReadOnly); + + QXmlSchema schema; + QVERIFY(schema.load(&buffer)); +} + +void tst_QXmlSchema::loadSchemaDeviceFail() const +{ + QByteArray data( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<xsd:schema" + " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"" + " xmlns=\"http://www.qtsoftware.com/xmlschematest\"" + " targetNamespace=\"http://www.qtsoftware.com/xmlschematest\"" + " version=\"1.0\"" + " elementFormDefault=\"qualified\">" + "</xsd:schema>" ); + + QBuffer buffer(&data); + // a closed device can not be loaded + + QXmlSchema schema; + QVERIFY(!schema.load(&buffer)); +} + +void tst_QXmlSchema::loadSchemaDataSuccess() const +{ + const QByteArray data( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<xsd:schema" + " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"" + " xmlns=\"http://www.qtsoftware.com/xmlschematest\"" + " targetNamespace=\"http://www.qtsoftware.com/xmlschematest\"" + " version=\"1.0\"" + " elementFormDefault=\"qualified\">" + "</xsd:schema>" ); + QXmlSchema schema; + QVERIFY(schema.load(data)); +} + +void tst_QXmlSchema::loadSchemaDataFail() const +{ + // empty schema can not be loaded + const QByteArray data; + + QXmlSchema schema; + QVERIFY(!schema.load(data)); +} + + void tst_QXmlSchema::networkAccessManagerSignature() const { /* Const object. */ @@ -185,7 +315,7 @@ void tst_QXmlSchema::messageHandler() const { /* Test that we return the message handler that was set. */ { - DummyMessageHandler handler; + MessageSilencer handler; QXmlSchema schema; schema.setMessageHandler(&handler); @@ -200,6 +330,13 @@ void tst_QXmlSchema::uriResolverSignature() const /* The function should be const. */ schema.uriResolver(); + + /* Const object. */ + const TestURIResolver resolver; + + /* This should compile */ + QXmlSchema schema2; + schema2.setUriResolver(&resolver); } void tst_QXmlSchema::uriResolverDefaultValue() const @@ -215,7 +352,7 @@ void tst_QXmlSchema::uriResolver() const { /* Test that we return the uri resolver that was set. */ { - DummyUriResolver resolver; + TestURIResolver resolver; QXmlSchema schema; schema.setUriResolver(&resolver); diff --git a/tests/auto/qxmlschemavalidator/tst_qxmlschemavalidator.cpp b/tests/auto/qxmlschemavalidator/tst_qxmlschemavalidator.cpp index b021b08..3bbf506 100644 --- a/tests/auto/qxmlschemavalidator/tst_qxmlschemavalidator.cpp +++ b/tests/auto/qxmlschemavalidator/tst_qxmlschemavalidator.cpp @@ -16,33 +16,8 @@ #include <QXmlSchema> #include <QXmlSchemaValidator> -class DummyMessageHandler : public QAbstractMessageHandler -{ - public: - DummyMessageHandler(QObject *parent = 0) - : QAbstractMessageHandler(parent) - { - } - - protected: - virtual void handleMessage(QtMsgType, const QString&, const QUrl&, const QSourceLocation&) - { - } -}; - -class DummyUriResolver : public QAbstractUriResolver -{ - public: - DummyUriResolver(QObject *parent = 0) - : QAbstractUriResolver(parent) - { - } - - virtual QUrl resolve(const QUrl&, const QUrl&) const - { - return QUrl(); - } -}; +#include "../qabstracturiresolver/TestURIResolver.h" +#include "../qxmlquery/MessageSilencer.h" /*! \class tst_QXmlSchemaValidatorValidator @@ -60,6 +35,13 @@ private Q_SLOTS: void defaultConstructor() const; void propertyInitialization() const; + void loadInstanceUrlSuccess() const; + void loadInstanceUrlFail() const; + void loadInstanceDeviceSuccess() const; + void loadInstanceDeviceFail() const; + void loadInstanceDataSuccess() const; + void loadInstanceDataFail() const; + void networkAccessManagerSignature() const; void networkAccessManagerDefaultValue() const; void networkAccessManager() const; @@ -73,6 +55,26 @@ private Q_SLOTS: void uriResolver() const; }; +static QXmlSchema createValidSchema() +{ + const QByteArray data( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<xsd:schema" + " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"" + " xmlns=\"http://www.qtsoftware.com/xmlschematest\"" + " targetNamespace=\"http://www.qtsoftware.com/xmlschematest\"" + " version=\"1.0\"" + " elementFormDefault=\"qualified\">" + " <xsd:element name=\"myRoot\" type=\"xsd:string\"/>" + "</xsd:schema>" ); + + const QUrl documentUri("http://www.qtsoftware.com/xmlschematest"); + + QXmlSchema schema; + schema.load(data, documentUri); + + return schema; +} + void tst_QXmlSchemaValidator::defaultConstructor() const { /* Allocate instance in different orders. */ @@ -101,8 +103,8 @@ void tst_QXmlSchemaValidator::propertyInitialization() const { /* Verify that properties set in the schema are used as default values for the validator */ { - DummyMessageHandler handler; - DummyUriResolver resolver; + MessageSilencer handler; + TestURIResolver resolver; QNetworkAccessManager manager; QXmlSchema schema; @@ -117,6 +119,72 @@ void tst_QXmlSchemaValidator::propertyInitialization() const } } +void tst_QXmlSchemaValidator::loadInstanceUrlSuccess() const +{ +/* + TODO: put valid schema file on given url and enable test + const QXmlSchema schema(createValidSchema()); + const QUrl url("http://notavailable/"); + + QXmlSchemaValidator validator(schema); + QVERIFY(!validator.validate(url)); +*/ +} + +void tst_QXmlSchemaValidator::loadInstanceUrlFail() const +{ + const QXmlSchema schema(createValidSchema()); + const QUrl url("http://notavailable/"); + + QXmlSchemaValidator validator(schema); + QVERIFY(!validator.validate(url)); +} + +void tst_QXmlSchemaValidator::loadInstanceDeviceSuccess() const +{ + const QXmlSchema schema(createValidSchema()); + + QByteArray data( "<myRoot xmlns=\"http://www.qtsoftware.com/xmlschematest\">Testme</myRoot>" ); + QBuffer buffer(&data); + buffer.open(QIODevice::ReadOnly); + + QXmlSchemaValidator validator(schema); + QVERIFY(validator.validate(&buffer)); +} + +void tst_QXmlSchemaValidator::loadInstanceDeviceFail() const +{ + const QXmlSchema schema(createValidSchema()); + + QByteArray data( "<myRoot xmlns=\"http://www.qtsoftware.com/xmlschematest\">Testme</myRoot>" ); + QBuffer buffer(&data); + // a closed device can not be loaded + + QXmlSchemaValidator validator(schema); + QVERIFY(!validator.validate(&buffer)); +} + +void tst_QXmlSchemaValidator::loadInstanceDataSuccess() const +{ + const QXmlSchema schema(createValidSchema()); + + const QByteArray data( "<myRoot xmlns=\"http://www.qtsoftware.com/xmlschematest\">Testme</myRoot>" ); + + QXmlSchemaValidator validator(schema); + QVERIFY(validator.validate(data)); +} + +void tst_QXmlSchemaValidator::loadInstanceDataFail() const +{ + const QXmlSchema schema(createValidSchema()); + + // empty instance can not be loaded + const QByteArray data; + + QXmlSchemaValidator validator(schema); + QVERIFY(!validator.validate(data)); +} + void tst_QXmlSchemaValidator::networkAccessManagerSignature() const { const QXmlSchema schema; @@ -202,7 +270,7 @@ void tst_QXmlSchemaValidator::messageHandlerDefaultValue() const { QXmlSchema schema; - DummyMessageHandler handler; + MessageSilencer handler; schema.setMessageHandler(&handler); const QXmlSchemaValidator validator(schema); @@ -214,7 +282,7 @@ void tst_QXmlSchemaValidator::messageHandler() const { /* Test that we return the message handler that was set. */ { - DummyMessageHandler handler; + MessageSilencer handler; const QXmlSchema schema; QXmlSchemaValidator validator(schema); @@ -225,7 +293,7 @@ void tst_QXmlSchemaValidator::messageHandler() const /* Test that we return the message handler that was set, even if the schema changed in between. */ { - DummyMessageHandler handler; + MessageSilencer handler; const QXmlSchema schema; QXmlSchemaValidator validator(schema); @@ -248,6 +316,13 @@ void tst_QXmlSchemaValidator::uriResolverSignature() const /* The function should be const. */ validator.uriResolver(); + + /* Const object. */ + const TestURIResolver resolver; + + /* This should compile */ + QXmlSchema schema2; + schema2.setUriResolver(&resolver); } void tst_QXmlSchemaValidator::uriResolverDefaultValue() const @@ -263,7 +338,7 @@ void tst_QXmlSchemaValidator::uriResolverDefaultValue() const { QXmlSchema schema; - DummyUriResolver resolver; + TestURIResolver resolver; schema.setUriResolver(&resolver); const QXmlSchemaValidator validator(schema); @@ -275,7 +350,7 @@ void tst_QXmlSchemaValidator::uriResolver() const { /* Test that we return the uri resolver that was set. */ { - DummyUriResolver resolver; + TestURIResolver resolver; const QXmlSchema schema; QXmlSchemaValidator validator(schema); @@ -286,7 +361,7 @@ void tst_QXmlSchemaValidator::uriResolver() const /* Test that we return the uri resolver that was set, even if the schema changed in between. */ { - DummyUriResolver resolver; + TestURIResolver resolver; const QXmlSchema schema; QXmlSchemaValidator validator(schema); diff --git a/tools/xmlpatternsvalidator/main.cpp b/tools/xmlpatternsvalidator/main.cpp index 032afc0..0ccbcfc 100644 --- a/tools/xmlpatternsvalidator/main.cpp +++ b/tools/xmlpatternsvalidator/main.cpp @@ -19,22 +19,29 @@ QT_USE_NAMESPACE -enum ExecutionMode -{ - InvalidMode, - SchemaOnlyMode, - SchemaAndInstanceMode, - InstanceOnlyMode -}; - int main(int argc, char **argv) { + enum ExitCode + { + Valid = 0, + Invalid, + ParseError + }; + + enum ExecutionMode + { + InvalidMode, + SchemaOnlyMode, + SchemaAndInstanceMode, + InstanceOnlyMode + }; + const QCoreApplication app(argc, argv); QCoreApplication::setApplicationName(QLatin1String("xmlpatternsvalidator")); if (argc != 2 && argc != 3) { qDebug() << QXmlPatternistCLI::tr("usage: xmlpatternsvalidator (<schema url> | <instance url> <schema url> | <instance url>)"); - return 2; + return ParseError; } // parse command line arguments @@ -63,9 +70,9 @@ int main(int argc, char **argv) schema.load(QUrl(schemaUri)); if (schema.isValid()) - return 0; + return Valid; else - return 1; + return Invalid; } else if (mode == SchemaAndInstanceMode) { const QString instanceUri = QFile::decodeName(argv[1]); const QString schemaUri = QFile::decodeName(argv[2]); @@ -73,24 +80,24 @@ int main(int argc, char **argv) schema.load(QUrl(schemaUri)); if (!schema.isValid()) - return 1; + return Invalid; QXmlSchemaValidator validator(schema); if (validator.validate(QUrl(instanceUri))) - return 0; + return Valid; else - return 1; + return Invalid; } else if (mode == InstanceOnlyMode) { const QString instanceUri = QFile::decodeName(argv[1]); QXmlSchemaValidator validator(schema); if (validator.validate(QUrl(instanceUri))) - return 0; + return Valid; else - return 1; + return Invalid; } Q_ASSERT(false); - return 1; + return Invalid; } |