/**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtXmlPatterns module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 3 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL3 included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 3 requirements ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 2.0 or (at your option) the GNU General ** Public license version 3 or any later version approved by the KDE Free ** Qt Foundation. The licenses are as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-2.0.html and ** https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_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_XsdValidatingInstanceReader_H #define Patternist_XsdValidatingInstanceReader_H #include #include #include #include #include QT_BEGIN_NAMESPACE class QXmlQuery; namespace QPatternist { /** * @short The validating schema instance reader. * * This class reads in a xml instance document from a QAbstractXmlNodeModel and * validates it against a given xml schema. * * @ingroup Patternist_schema * @author Tobias Koenig */ class XsdValidatingInstanceReader : public XsdInstanceReader { public: typedef QExplicitlySharedDataPointer Ptr; /** * Creates a new validating instance reader that reads the data from * the given @p model. * * @param model The model the data shall be read from. * @param documentUri The uri of the document the model is from. * @param context The context that is used to report errors etc. */ XsdValidatingInstanceReader(XsdValidatedXmlNodeModel *model, const QUrl &documentUri, const XsdSchemaContext::Ptr &context); /** * Adds a new @p schema to the pool of schemas that shall be used * for validation. * The schema is located at the given @p url. */ void addSchema(const XsdSchema::Ptr &schema, const QUrl &url); /** * Reads and validates the instance document. */ bool read(); private: /** * Loads a schema with the given @p targetNamespace from the given @p location * and adds it to the pool of schemas that are used for validation. * * This method is used to load schemas defined in the xsi:schemaLocation or * xsi:noNamespaceSchemaLocation attributes in the instance document. */ bool loadSchema(const QString &targetNamespace, const QUrl &location); /** * Reports an error via the report context. */ void error(const QString &msg) const; /** * Validates the current element tag of the instance document. * * @param hasStateMachine Used to remember whether this element represents the start tag * of a complex type and therefor pushes a new state machine on the stack. * @param element Used to remember which element has been validated in this step. */ bool validate(bool &hasStateMachine, XsdElement::Ptr &element); /** * Validates the current tag of the instance document against the given element @p declaration. * * @param declaration The element declaration to validate against. * @param hasStateMachine Used to remember whether this element represents the start tag * of a complex type and therefor pushes a new state machine on the stack. */ bool validateElement(const XsdElement::Ptr &declaration, bool &hasStateMachine); /** * Validates the current tag of the instance document against the given @p type of the element @p declaration. * * @param declaration The element declaration to validate against. * @param type The type to validate against. * @param isNilled Defines whether the element is nilled by the instance document. * @param hasStateMachine Used to remember whether this element represents the start tag * of a complex type and therefor pushes a new state machine on the stack. * * @note The @p type can differ from the element @p declaration type if the instance document has defined * it via xsi:type attribute. */ bool validateElementType(const XsdElement::Ptr &declaration, const SchemaType::Ptr &type, bool isNilled, bool &hasStateMachine); /** * Validates the current tag of the instance document against the given simple @p type of the element @p declaration. * * @param declaration The element declaration to validate against. * @param type The type to validate against. * @param isNilled Defines whether the element is nilled by the instance document. * * @note The @p type can differ from the element @p declaration type if the instance document has defined * it via xsi:type attribute. */ bool validateElementSimpleType(const XsdElement::Ptr &declaration, const SchemaType::Ptr &type, bool isNilled); /** * Validates the current tag of the instance document against the given complex @p type of the element @p declaration. * * @param declaration The element declaration to validate against. * @param type The type to validate against. * @param isNilled Defines whether the element is nilled by the instance document. * @param hasStateMachine Used to remember whether this element represents the start tag * of a complex type and therefor pushes a new state machine on the stack. * * @note The @p type can differ from the element @p declaration type if the instance document has defined * it via xsi:type attribute. */ bool validateElementComplexType(const XsdElement::Ptr &declaration, const SchemaType::Ptr &type, bool isNilled, bool &hasStateMachine); /** * Validates the given @p value against the attribute use @p declaration. */ bool validateAttribute(const XsdAttributeUse::Ptr &declaration, const QString &value); /** * Validates the given @p value against the attribute @p declaration. */ bool validateAttribute(const XsdAttribute::Ptr &declaration, const QString &value); /** * Validates the given @p attributeName against the @p wildcard. */ bool validateAttributeWildcard(const QXmlName &attributeName, const XsdWildcard::Ptr &wildcard); /** * Validates the identity constraints of an @p element. */ bool validateIdentityConstraint(const XsdElement::Ptr &element, const QXmlItem ¤tItem); /** * Validates the unique identity @p constraint of the @p element. */ bool validateUniqueIdentityConstraint(const XsdElement::Ptr &element, const XsdIdentityConstraint::Ptr &constraint, const TargetNode::Set &qualifiedNodeSet); /** * Validates the key identity @p constraint of the @p element. */ bool validateKeyIdentityConstraint(const XsdElement::Ptr &element, const XsdIdentityConstraint::Ptr &constraint, const TargetNode::Set &targetNodeSet, const TargetNode::Set &qualifiedNodeSet); /** * Validates the keyref identity @p constraint of the @p element. */ bool validateKeyRefIdentityConstraint(const XsdElement::Ptr &element, const XsdIdentityConstraint::Ptr &constraint, const TargetNode::Set &qualifiedNodeSet); /** * Selects two sets of nodes that match the given identity @p constraint. * * @param element The element the identity constraint belongs to. * @param currentItem The current element that will be used as focus for the XQuery. * @param constraint The constraint (selector and fields) that describe the two sets. * @param targetNodeSet The target node set as defined by the schema specification. * @param qualifiedNodeSet The qualified node set as defined by the schema specification. */ bool selectNodeSets(const XsdElement::Ptr &element, const QXmlItem ¤tItem, const XsdIdentityConstraint::Ptr &constraint, TargetNode::Set &targetNodeSet, TargetNode::Set &qualifiedNodeSet); /** * Creates an QXmlQuery object with the defined @p namespaceBindings that has the @p contextNode as focus * and will execute @p query. */ QXmlQuery createXQuery(const QList &namespaceBindings, const QXmlItem &contextNode, const QString &query) const; /** * Returns the element declaration with the given @p name from the pool of all schemas. */ XsdElement::Ptr elementByName(const QXmlName &name) const; /** * Returns the attribute declaration with the given @p name from the pool of all schemas. */ XsdAttribute::Ptr attributeByName(const QXmlName &name) const; /** * Returns the type declaration with the given @p name from the pool of all schemas. */ SchemaType::Ptr typeByName(const QXmlName &name) const; /** * Adds the ID/IDREF binding to the validated model and checks for duplicates. */ void addIdIdRefBinding(const QString &id, const NamedSchemaComponent::Ptr &binding); /** * Helper method that reads an attribute of type xs:QName and does * syntax checking. */ QString qNameAttribute(const QXmlName &attributeName); /** * Returns the xs:anyType that is used to build up the state machine. * We need that as the BuiltinTypes::xsAnyType is not a XsdComplexType. */ XsdComplexType::Ptr anyType(); /** * Helper method that creates a state machine for the given @p particle * and pushes it on the state machine stack. */ void createAndPushStateMachine(const XsdParticle::Ptr &particle); typedef QHash MergedSchemas; XsdValidatedXmlNodeModel::Ptr m_model; MergedSchemas m_mergedSchemas; XsdSchema::Ptr m_schema; const NamePool::Ptr m_namePool; const QXmlName m_xsiNilName; const QXmlName m_xsiTypeName; const QXmlName m_xsiSchemaLocationName; const QXmlName m_xsiNoNamespaceSchemaLocationName; QStack > m_stateMachines; QUrl m_documentUri; XsdComplexType::Ptr m_anyType; QSet m_processedNamespaces; QSet m_processedSchemaLocations; QSet m_idRefs; QHash m_idcKeys; SchemaType::Ptr m_idRefsType; }; } QT_END_NAMESPACE #endif