Qt 4.8
Public Types | Public Functions | Private Types | Private Functions | Properties | List of all members
QPatternist::XsdSchemaChecker Class Reference

Encapsulates the checking of schema valitity after reference resolving has finished. More...

#include <qxsdschemachecker_p.h>

Inheritance diagram for QPatternist::XsdSchemaChecker:
QSharedData

Public Types

typedef QExplicitlySharedDataPointer< XsdSchemaCheckerPtr
 

Public Functions

void addComponentLocationHash (const QHash< NamedSchemaComponent::Ptr, QSourceLocation > &hash)
 
void basicCheck ()
 
void check ()
 
void checkConstrainingFacets ()
 
 XsdSchemaChecker (const QExplicitlySharedDataPointer< XsdSchemaContext > &context, const XsdSchemaParserContext *parserContext)
 
 ~XsdSchemaChecker ()
 
- Public Functions inherited from QSharedData
 QSharedData ()
 Constructs a QSharedData object with a reference count of 0. More...
 
 QSharedData (const QSharedData &)
 Constructs a QSharedData object with reference count 0. More...
 

Private Types

typedef QHash< QXmlName, SchemaType::PtrDuplicatedElementMap
 
typedef QHash< XsdWildcard::NamespaceConstraint::Variety, XsdWildcard::PtrDuplicatedWildcardMap
 

Private Functions

void checkAttributeConstraints ()
 
void checkAttributeUseConstraints ()
 
void checkBasicCircularInheritances ()
 
void checkBasicComplexTypeConstraints ()
 
void checkBasicSimpleTypeConstraints ()
 
void checkCircularInheritances ()
 
void checkComplexTypeConstraints ()
 
void checkConstrainingFacets (const XsdFacet::Hash &facets, const XsdSimpleType::Ptr &simpleType)
 
void checkDuplicatedAttributeUses ()
 
void checkElementConstraints ()
 
void checkElementDuplicates ()
 
void checkElementDuplicates (const XsdParticle::Ptr &particle, DuplicatedElementMap &elementMap, DuplicatedWildcardMap &wildcardMap)
 
void checkInheritanceRestrictions ()
 
void checkSimpleDerivationRestrictions ()
 
void checkSimpleRestrictionBaseType ()
 
void checkSimpleTypeConstraints ()
 
bool elementSequenceAccepted (const XsdModelGroup::Ptr &sequence, const XsdParticle::Ptr &particle) const
 
XsdFacet::Hash facetsForType (const SchemaType::Ptr &type) const
 
bool hasConstraintIDAttributeUse (const XsdAttributeUse::List &list, XsdAttribute::Ptr &conflictingAttribute) const
 
bool hasDuplicatedAttributeUses (const XsdAttributeUse::List &list, XsdAttribute::Ptr &conflictingAttribute) const
 
bool hasMultipleIDAttributeUses (const XsdAttributeUse::List &list) const
 
bool isValidParticleExtension (const XsdParticle::Ptr &extension, const XsdParticle::Ptr &base) const
 
bool isValidValue (const QString &value, const AnySimpleType::Ptr &type, QString &errorMsg) const
 
bool particleEqualsRecursively (const XsdParticle::Ptr &particle, const XsdParticle::Ptr &otherParticle) const
 
void setupAllowedAtomicFacets ()
 
QSourceLocation sourceLocation (const NamedSchemaComponent::Ptr &component) const
 
QSourceLocation sourceLocationForType (const SchemaType::Ptr &type) const
 

Properties

QHash< QXmlName, QSet< XsdFacet::Type > > m_allowedAtomicFacets
 
QHash< NamedSchemaComponent::Ptr, QSourceLocationm_componentLocationHash
 
QExplicitlySharedDataPointer< XsdSchemaContextm_context
 
NamePool::Ptr m_namePool
 
XsdSchema::Ptr m_schema
 

Additional Inherited Members

- Public Variables inherited from QSharedData
QAtomicInt ref
 

Detailed Description

Encapsulates the checking of schema valitity after reference resolving has finished.

Author
Tobias Koenig tobia.nosp@m.s.ko.nosp@m.enig@.nosp@m.noki.nosp@m.a.com

Definition at line 81 of file qxsdschemachecker_p.h.

Typedefs

◆ DuplicatedElementMap

A map used to find duplicated elements inside a model group.

Definition at line 188 of file qxsdschemachecker_p.h.

◆ DuplicatedWildcardMap

A map used to find duplicated wildcards inside a model group.

Definition at line 193 of file qxsdschemachecker_p.h.

◆ Ptr

Definition at line 84 of file qxsdschemachecker_p.h.

Constructors and Destructors

◆ XsdSchemaChecker()

XsdSchemaChecker::XsdSchemaChecker ( const QExplicitlySharedDataPointer< XsdSchemaContext > &  context,
const XsdSchemaParserContext parserContext 
)

Creates a new schema checker.

Parameters
contextThe context that is used for customization.
parserContextThe context that contains all the data structures.

Definition at line 65 of file qxsdschemachecker.cpp.

66  : m_context(context)
67  , m_namePool(parserContext->namePool())
68  , m_schema(parserContext->schema())
69 {
71 }
QExplicitlySharedDataPointer< XsdSchemaContext > m_context

◆ ~XsdSchemaChecker()

XsdSchemaChecker::~XsdSchemaChecker ( )

Destroys the schema checker.

Definition at line 73 of file qxsdschemachecker.cpp.

74 {
75 }

Functions

◆ addComponentLocationHash()

void XsdSchemaChecker::addComponentLocationHash ( const QHash< NamedSchemaComponent::Ptr, QSourceLocation > &  hash)

Adds the component location hash, so the checker is able to report meaning full error messages.

Definition at line 108 of file qxsdschemachecker.cpp.

Referenced by QPatternist::XsdSchemaResolver::resolve().

109 {
111 }
QHash< NamedSchemaComponent::Ptr, QSourceLocation > m_componentLocationHash
QHash< Key, T > & unite(const QHash< Key, T > &other)
Inserts all the items in the other hash into this hash.
Definition: qhash.h:556

◆ basicCheck()

void XsdSchemaChecker::basicCheck ( )

Starts a basic check process.

This check only validates the basic super type inheritance of simple and complex types.

Definition at line 82 of file qxsdschemachecker.cpp.

Referenced by QPatternist::XsdSchemaResolver::resolve().

83 {
84  // first check that there is no circular inheritance, only the
85  // wxsSuperType is used here
87 
88  // check the basic constraints like simple type can not inherit from complex type etc.
91 }

◆ check()

void XsdSchemaChecker::check ( )

Starts the real check process.

Definition at line 93 of file qxsdschemachecker.cpp.

Referenced by QPatternist::XsdSchemaResolver::resolve().

94 {
101 
105 // checkElementDuplicates();
106 }

◆ checkAttributeConstraints()

void XsdSchemaChecker::checkAttributeConstraints ( )
private

Check the attribute constraints.

Definition at line 1809 of file qxsdschemachecker.cpp.

Referenced by check().

1810 {
1811  // all global attributes
1812  XsdAttribute::List attributes = m_schema->attributes();
1813 
1814  // and all local attributes
1816  types << m_schema->anonymousTypes();
1817 
1818  for (int i = 0; i < types.count(); ++i) {
1819  if (!types.at(i)->isComplexType() || !types.at(i)->isDefinedBySchema())
1820  continue;
1821 
1822  const XsdComplexType::Ptr complexType(types.at(i));
1823  const XsdAttributeUse::List uses = complexType->attributeUses();
1824  for (int j = 0; j < uses.count(); ++j)
1825  attributes.append(uses.at(j)->attribute());
1826  }
1827 
1828  for (int i = 0; i < attributes.count(); ++i) {
1829  const XsdAttribute::Ptr attribute = attributes.at(i);
1830 
1831  if (!attribute->valueConstraint())
1832  continue;
1833 
1834  if (attribute->valueConstraint()->variety() == XsdAttribute::ValueConstraint::Default || attribute->valueConstraint()->variety() == XsdAttribute::ValueConstraint::Fixed) {
1835  const SchemaType::Ptr type = attribute->type();
1836 
1837  QString errorMsg;
1838  if (!isValidValue(attribute->valueConstraint()->value(), attribute->type(), errorMsg)) {
1839  m_context->error(QtXmlPatterns::tr("Value constraint of attribute %1 is not of attributes type: %2.")
1840  .arg(formatKeyword(attribute->displayName(m_namePool)))
1841  .arg(errorMsg),
1843  return;
1844  }
1845  }
1846 
1847  if (BuiltinTypes::xsID->wxsTypeMatches(attribute->type())) {
1848  m_context->error(QtXmlPatterns::tr("Attribute %1 has value constraint but has type derived from %2.")
1849  .arg(formatKeyword(attribute->displayName(m_namePool)))
1852  return;
1853  }
1854  }
1855 }
static const AtomicType::Ptr xsID
int type
Definition: qmetatype.cpp:239
QExplicitlySharedDataPointer< XsdSchemaContext > m_context
The attribute has a default value set.
QString formatKeyword(const QString &keyword)
QString formatType(const NamePool::Ptr &np, const T &type)
Formats ItemType and SequenceType.
QSourceLocation sourceLocation(const NamedSchemaComponent::Ptr &component) const
bool isValidValue(const QString &value, const AnySimpleType::Ptr &type, QString &errorMsg) const
ValueConstraint::Ptr valueConstraint() const
SchemaType::List anonymousTypes() const
Definition: qxsdschema.cpp:181
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
The QString class provides a Unicode character string.
Definition: qstring.h:83
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
void error(const QString &message, const ReportContext::ErrorCode errorCode, const QSourceLocation &sourceLocation)
AnySimpleType::Ptr type() const
virtual bool isComplexType() const
Definition: qschematype.cpp:70
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
virtual QString displayName(const NamePool::Ptr &namePool) const
static const struct @32 types[]
static bool wxsTypeMatches(const SchemaType::Ptr &type, const SchemaType::Ptr &otherType, QSet< SchemaType::Ptr > &visitedTypes, SchemaType::Ptr &conflictingType)
XsdAttribute::List attributes() const
Definition: qxsdschema.cpp:110
The attribute has a fixed value set.
virtual bool isDefinedBySchema() const
Definition: qschematype.cpp:75
SchemaType::List types() const
Definition: qxsdschema.cpp:131
The QList class is a template class that provides lists.
Definition: qdatastream.h:62

◆ checkAttributeUseConstraints()

void XsdSchemaChecker::checkAttributeUseConstraints ( )
private

Check the attribute use constraints.

Definition at line 1869 of file qxsdschemachecker.cpp.

Referenced by check().

1870 {
1871  XsdComplexType::List complexTypes;
1872 
1874  types << m_schema->anonymousTypes();
1875 
1876  for (int i = 0; i < types.count(); ++i) {
1877  const SchemaType::Ptr type = types.at(i);
1878  if (type->isComplexType() && type->isDefinedBySchema())
1879  complexTypes.append(XsdComplexType::Ptr(type));
1880  }
1881 
1882  for (int i = 0; i < complexTypes.count(); ++i) {
1883  const XsdComplexType::Ptr complexType(complexTypes.at(i));
1884  const SchemaType::Ptr baseType = complexType->wxsSuperType();
1885  if (!baseType || !baseType->isComplexType() || !baseType->isDefinedBySchema())
1886  continue;
1887 
1888  const XsdComplexType::Ptr complexBaseType(baseType);
1889 
1890  const XsdAttributeUse::List attributeUses = complexType->attributeUses();
1892  for (int j = 0; j < attributeUses.count(); ++j)
1893  lookupHash.insert(attributeUses.at(j)->attribute()->name(m_namePool), attributeUses.at(j));
1894 
1895  const XsdAttributeUse::List baseAttributeUses = complexBaseType->attributeUses();
1896  for (int j = 0; j < baseAttributeUses.count(); ++j) {
1897  const XsdAttributeUse::Ptr baseAttributeUse = baseAttributeUses.at(j);
1898 
1899  if (lookupHash.contains(baseAttributeUse->attribute()->name(m_namePool))) {
1900  const XsdAttributeUse::Ptr attributeUse = lookupHash.value(baseAttributeUse->attribute()->name(m_namePool));
1901 
1902  if (baseAttributeUse->useType() == XsdAttributeUse::RequiredUse) {
1903  if (attributeUse->useType() == XsdAttributeUse::OptionalUse || attributeUse->useType() == XsdAttributeUse::ProhibitedUse) {
1904  m_context->error(QtXmlPatterns::tr("%1 attribute in derived complex type must be %2 like in base type.")
1905  .arg(formatAttribute("use"))
1906  .arg(formatData("required")),
1908  return;
1909  }
1910  }
1911 
1912  if (baseAttributeUse->valueConstraint()) {
1913  if (baseAttributeUse->valueConstraint()->variety() == XsdAttributeUse::ValueConstraint::Fixed) {
1914  if (!attributeUse->valueConstraint()) {
1915  m_context->error(QtXmlPatterns::tr("Attribute %1 in derived complex type must have %2 value constraint like in base type.")
1916  .arg(formatKeyword(attributeUse->attribute()->displayName(m_namePool)))
1917  .arg(formatData("fixed")),
1919  return;
1920  } else {
1921  if (attributeUse->valueConstraint()->variety() == XsdAttributeUse::ValueConstraint::Fixed) {
1922  const XsdTypeChecker checker(m_context, QVector<QXmlName>(), sourceLocation(complexType));
1923  if (!checker.valuesAreEqual(attributeUse->valueConstraint()->value(), baseAttributeUse->valueConstraint()->value(), attributeUse->attribute()->type())) {
1924  m_context->error(QtXmlPatterns::tr("Attribute %1 in derived complex type must have the same %2 value constraint like in base type.")
1925  .arg(formatKeyword(attributeUse->attribute()->displayName(m_namePool)))
1926  .arg(formatData("fixed")),
1928  return;
1929  }
1930  } else {
1931  m_context->error(QtXmlPatterns::tr("Attribute %1 in derived complex type must have %2 value constraint.")
1932  .arg(formatKeyword(attributeUse->attribute()->displayName(m_namePool)))
1933  .arg(formatData("fixed")),
1935  return;
1936  }
1937  }
1938  }
1939  }
1940  }
1941  }
1942 
1943  // additional check that process content property of attribute wildcard in derived type is
1944  // not weaker than the wildcard in base type
1945  const XsdWildcard::Ptr baseWildcard(complexBaseType->attributeWildcard());
1946  const XsdWildcard::Ptr derivedWildcard(complexType->attributeWildcard());
1947  if (baseWildcard && derivedWildcard) {
1948  if (!XsdSchemaHelper::checkWildcardProcessContents(baseWildcard, derivedWildcard)) {
1949  m_context->error(QtXmlPatterns::tr("processContent of base wildcard must be weaker than derived wildcard."), XsdSchemaContext::XSDError, sourceLocation(complexType));
1950  return;
1951  }
1952  }
1953  }
1954 }
int type
Definition: qmetatype.cpp:239
QExplicitlySharedDataPointer< XsdSchemaContext > m_context
QString formatKeyword(const QString &keyword)
The attribute use has a fixed value set.
QSourceLocation sourceLocation(const NamedSchemaComponent::Ptr &component) const
The attribute is not allowed to be there.
The attribute can be there but doesn&#39;t need to.
SchemaType::List anonymousTypes() const
Definition: qxsdschema.cpp:181
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
The QHash class is a template class that provides a hash-table-based dictionary.
Definition: qdatastream.h:66
bool contains(const Key &key) const
Returns true if the hash contains an item with the key; otherwise returns false.
Definition: qhash.h:872
const T value(const Key &key) const
Returns the value associated with the key.
Definition: qhash.h:606
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition: qhash.h:753
void error(const QString &message, const ReportContext::ErrorCode errorCode, const QSourceLocation &sourceLocation)
static bool checkWildcardProcessContents(const XsdWildcard::Ptr &baseWildcard, const XsdWildcard::Ptr &derivedWildcard)
virtual bool isComplexType() const
Definition: qschematype.cpp:70
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
static QString formatData(const QString &data)
static const struct @32 types[]
QList< SchemaType::Ptr > List
Definition: qschematype_p.h:84
static QString formatAttribute(const QString &attribute)
Formats attribute name.
virtual bool isDefinedBySchema() const
Definition: qschematype.cpp:75
SchemaType::List types() const
Definition: qxsdschema.cpp:131
The class that provides methods for checking a string against a type.
virtual SchemaType::Ptr wxsSuperType() const =0

◆ checkBasicCircularInheritances()

void XsdSchemaChecker::checkBasicCircularInheritances ( )
private

Checks that no simple or complex type inherits itself.

Definition at line 207 of file qxsdschemachecker.cpp.

Referenced by basicCheck().

208 {
209  // check all global types...
211 
212  // .. and anonymous types
213  types << m_schema->anonymousTypes();
214 
215  for (int i = 0; i < types.count(); ++i) {
216  const SchemaType::Ptr type = types.at(i);
218 
219  // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 3)
220 
221  // check normal base type inheritance
222  QSet<SchemaType::Ptr> visitedTypes;
223  SchemaType::Ptr conflictingType;
224 
225  if (wxsTypeMatches(type, type->wxsSuperType(), visitedTypes, conflictingType)) {
226  if (conflictingType)
227  m_context->error(QtXmlPatterns::tr("%1 has inheritance loop in its base type %2.")
228  .arg(formatType(m_namePool, type))
229  .arg(formatType(m_namePool, conflictingType)),
230  XsdSchemaContext::XSDError, location);
231  else
232  m_context->error(QtXmlPatterns::tr("Circular inheritance of base type %1.").arg(formatType(m_namePool, type)), XsdSchemaContext::XSDError, location);
233 
234  return;
235  }
236  }
237 }
int type
Definition: qmetatype.cpp:239
QExplicitlySharedDataPointer< XsdSchemaContext > m_context
QString formatType(const NamePool::Ptr &np, const T &type)
Formats ItemType and SequenceType.
SchemaType::List anonymousTypes() const
Definition: qxsdschema.cpp:181
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
void error(const QString &message, const ReportContext::ErrorCode errorCode, const QSourceLocation &sourceLocation)
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
The QSourceLocation class identifies a location in a resource by URI, line, and column.
static const struct @32 types[]
static bool wxsTypeMatches(const SchemaType::Ptr &type, const SchemaType::Ptr &otherType, QSet< SchemaType::Ptr > &visitedTypes, SchemaType::Ptr &conflictingType)
static QTestResult::TestLocation location
Definition: qtestresult.cpp:63
SchemaType::List types() const
Definition: qxsdschema.cpp:131
QSourceLocation sourceLocationForType(const SchemaType::Ptr &type) const
virtual SchemaType::Ptr wxsSuperType() const =0

◆ checkBasicComplexTypeConstraints()

void XsdSchemaChecker::checkBasicComplexTypeConstraints ( )
private

Checks for various constraints for complex types defined by schema.

Definition at line 608 of file qxsdschemachecker.cpp.

Referenced by basicCheck().

609 {
610  // check all global types...
612 
613  // .. and anonymous types
614  types << m_schema->anonymousTypes();
615 
616  for (int i = 0; i < types.count(); ++i) {
617  const SchemaType::Ptr type = types.at(i);
618 
619  if (!type->isComplexType() || !type->isDefinedBySchema())
620  continue;
621 
622  const XsdComplexType::Ptr complexType = type;
623 
624  const QSourceLocation location = sourceLocation(complexType);
625 
626  // check inheritance restrictions of complex type defined by schema constraints
627  const SchemaType::Ptr baseType = complexType->wxsSuperType();
628 
629  // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 2)
630  if (baseType->isSimpleType() && (complexType->derivationMethod() != XsdComplexType::DerivationExtension)) {
631  m_context->error(QtXmlPatterns::tr("Derivation method of %1 must be extension because the base type %2 is a simple type.")
632  .arg(formatType(m_namePool, complexType))
633  .arg(formatType(m_namePool, baseType)),
634  XsdSchemaContext::XSDError, location);
635  return;
636  }
637  }
638 }
int type
Definition: qmetatype.cpp:239
QExplicitlySharedDataPointer< XsdSchemaContext > m_context
virtual bool isSimpleType() const
Definition: qschematype.cpp:56
QString formatType(const NamePool::Ptr &np, const T &type)
Formats ItemType and SequenceType.
QSourceLocation sourceLocation(const NamedSchemaComponent::Ptr &component) const
SchemaType::List anonymousTypes() const
Definition: qxsdschema.cpp:181
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
virtual SchemaType::Ptr wxsSuperType() const
void error(const QString &message, const ReportContext::ErrorCode errorCode, const QSourceLocation &sourceLocation)
virtual bool isComplexType() const
Definition: qschematype.cpp:70
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
The QSourceLocation class identifies a location in a resource by URI, line, and column.
virtual DerivationMethod derivationMethod() const
static const struct @32 types[]
static QTestResult::TestLocation location
Definition: qtestresult.cpp:63
virtual bool isDefinedBySchema() const
Definition: qschematype.cpp:75
SchemaType::List types() const
Definition: qxsdschema.cpp:131

◆ checkBasicSimpleTypeConstraints()

void XsdSchemaChecker::checkBasicSimpleTypeConstraints ( )
private

Checks for various constraints for simple types defined by schema.

Definition at line 306 of file qxsdschemachecker.cpp.

Referenced by basicCheck().

307 {
308  // check all global types...
310 
311  // .. and anonymous types
312  types << m_schema->anonymousTypes();
313 
314  for (int i = 0; i < types.count(); ++i) {
315  const SchemaType::Ptr type = types.at(i);
316 
317  if (!type->isSimpleType())
318  continue;
319 
320  const XsdSimpleType::Ptr simpleType = type;
321 
322  const QSourceLocation location = sourceLocation(simpleType);
323 
324  // check inheritance restrictions of simple type defined by schema constraints
325  const SchemaType::Ptr baseType = simpleType->wxsSuperType();
326 
327  if (baseType->isComplexType() && (simpleType->name(m_namePool) != BuiltinTypes::xsAnySimpleType->name(m_namePool))) {
328  m_context->error(QtXmlPatterns::tr("Base type of simple type %1 cannot be complex type %2.")
329  .arg(formatType(m_namePool, simpleType))
330  .arg(formatType(m_namePool, baseType)),
331  XsdSchemaContext::XSDError, location);
332  return;
333  }
334 
335  if (baseType == BuiltinTypes::xsAnyType) {
337  m_context->error(QtXmlPatterns::tr("Simple type %1 cannot have direct base type %2.")
338  .arg(formatType(m_namePool, simpleType))
340  XsdSchemaContext::XSDError, location);
341  return;
342  }
343  }
344  }
345 }
int type
Definition: qmetatype.cpp:239
QExplicitlySharedDataPointer< XsdSchemaContext > m_context
virtual bool isSimpleType() const
Definition: qschematype.cpp:56
QString formatType(const NamePool::Ptr &np, const T &type)
Formats ItemType and SequenceType.
QSourceLocation sourceLocation(const NamedSchemaComponent::Ptr &component) const
SchemaType::List anonymousTypes() const
Definition: qxsdschema.cpp:181
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
static const SchemaType::Ptr xsAnyType
virtual SchemaType::Ptr wxsSuperType() const
void error(const QString &message, const ReportContext::ErrorCode errorCode, const QSourceLocation &sourceLocation)
virtual bool isComplexType() const
Definition: qschematype.cpp:70
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
The QSourceLocation class identifies a location in a resource by URI, line, and column.
static const struct @32 types[]
static const SchemaType::Ptr xsAnySimpleType
static QTestResult::TestLocation location
Definition: qtestresult.cpp:63
SchemaType::List types() const
Definition: qxsdschema.cpp:131
virtual QXmlName name(const NamePool::Ptr &namePool) const
virtual QXmlName name(const NamePool::Ptr &np) const =0
Returns the name of the type.

◆ checkCircularInheritances()

void XsdSchemaChecker::checkCircularInheritances ( )
private

Checks the advanced circular inheritance.

Definition at line 239 of file qxsdschemachecker.cpp.

Referenced by check().

240 {
241  // check all global types...
243 
244  // .. and anonymous types
245  types << m_schema->anonymousTypes();
246 
247  for (int i = 0; i < types.count(); ++i) {
248  const SchemaType::Ptr type = types.at(i);
250 
251  // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 3)
252 
253  // check normal base type inheritance
254  QSet<SchemaType::Ptr> visitedTypes;
255  if (matchesType(type, type->wxsSuperType(), visitedTypes)) {
256  m_context->error(QtXmlPatterns::tr("Circular inheritance of base type %1.").arg(formatType(m_namePool, type)), XsdSchemaContext::XSDError, location);
257  return;
258  }
259 
260  // check union member inheritance
261  if (type->isSimpleType() && type->isDefinedBySchema()) {
262  const XsdSimpleType::Ptr simpleType = type;
263  if (simpleType->category() == XsdSimpleType::SimpleTypeUnion) {
264  const XsdSimpleType::List memberTypes = simpleType->memberTypes();
265  for (int j = 0; j < memberTypes.count(); ++j) {
266  if (hasCircularUnionInheritance(simpleType, memberTypes.at(j), m_namePool)) {
267  m_context->error(QtXmlPatterns::tr("Circular inheritance of union %1.").arg(formatType(m_namePool, type)), XsdSchemaContext::XSDError, location);
268  return;
269  }
270  }
271  }
272  }
273  }
274 }
int type
Definition: qmetatype.cpp:239
virtual TypeCategory category() const
QExplicitlySharedDataPointer< XsdSchemaContext > m_context
virtual bool isSimpleType() const
Definition: qschematype.cpp:56
QString formatType(const NamePool::Ptr &np, const T &type)
Formats ItemType and SequenceType.
SchemaType::List anonymousTypes() const
Definition: qxsdschema.cpp:181
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
static bool matchesType(const SchemaType::Ptr &myType, const SchemaType::Ptr &otherType, QSet< SchemaType::Ptr > visitedTypes)
void error(const QString &message, const ReportContext::ErrorCode errorCode, const QSourceLocation &sourceLocation)
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
The QSourceLocation class identifies a location in a resource by URI, line, and column.
QList< AnySimpleType::Ptr > List
static const struct @32 types[]
static QTestResult::TestLocation location
Definition: qtestresult.cpp:63
static bool hasCircularUnionInheritance(const XsdSimpleType::Ptr &type, const SchemaType::Ptr &otherType, NamePool::Ptr &namePool)
AnySimpleType::List memberTypes() const
virtual bool isDefinedBySchema() const
Definition: qschematype.cpp:75
SchemaType::List types() const
Definition: qxsdschema.cpp:131
QSourceLocation sourceLocationForType(const SchemaType::Ptr &type) const
virtual SchemaType::Ptr wxsSuperType() const =0

◆ checkComplexTypeConstraints()

void XsdSchemaChecker::checkComplexTypeConstraints ( )
private

Definition at line 640 of file qxsdschemachecker.cpp.

Referenced by check().

641 {
642  // check all global types...
644 
645  // .. and anonymous types
646  types << m_schema->anonymousTypes();
647 
648  for (int i = 0; i < types.count(); ++i) {
649  const SchemaType::Ptr type = types.at(i);
650 
651  if (!type->isComplexType() || !type->isDefinedBySchema())
652  continue;
653 
654  const XsdComplexType::Ptr complexType = type;
655 
656  const QSourceLocation location = sourceLocation(complexType);
657 
658  if (complexType->contentType()->particle()) {
659  XsdElement::Ptr duplicatedElement;
660  if (XsdParticleChecker::hasDuplicatedElements(complexType->contentType()->particle(), m_namePool, duplicatedElement)) {
661  m_context->error(QtXmlPatterns::tr("Complex type %1 has duplicated element %2 in its content model.")
662  .arg(formatType(m_namePool, complexType))
663  .arg(formatKeyword(duplicatedElement->displayName(m_namePool))),
665  return;
666  }
667 
668  if (!XsdParticleChecker::isUPAConform(complexType->contentType()->particle(), m_namePool)) {
669  m_context->error(QtXmlPatterns::tr("Complex type %1 has non-deterministic content.")
670  .arg(formatType(m_namePool, complexType)),
671  XsdSchemaContext::XSDError, location);
672  return;
673  }
674  }
675 
676  // check inheritance restrictions of complex type defined by schema constraints
677  const SchemaType::Ptr baseType = complexType->wxsSuperType();
678 
679  // @see http://www.w3.org/TR/xmlschema11-1/#cos-ct-extends
681  if (baseType->isComplexType() && baseType->isDefinedBySchema()) {
682  const XsdComplexType::Ptr complexBaseType = baseType;
683 
684  // we can skip 1.1 here, as it is tested in checkInheritanceRestrictions() already
685 
686  // 1.2 and 1.3
687  QString errorMsg;
688  if (!XsdSchemaHelper::isValidAttributeUsesExtension(complexType->attributeUses(), complexBaseType->attributeUses(),
689  complexType->attributeWildcard(), complexBaseType->attributeWildcard(), m_context, errorMsg)) {
690  m_context->error(QtXmlPatterns::tr("Attributes of complex type %1 are not a valid extension of the attributes of base type %2: %3.")
691  .arg(formatType(m_namePool, complexType))
692  .arg(formatType(m_namePool, baseType))
693  .arg(errorMsg),
694  XsdSchemaContext::XSDError, location);
695  return;
696  }
697 
698  // 1.4
699  bool validContentType = false;
700  if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple && complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Simple) {
701  if (complexType->contentType()->simpleType() == complexBaseType->contentType()->simpleType()) {
702  validContentType = true; // 1.4.1
703  }
704  } else if (complexType->contentType()->variety() == XsdComplexType::ContentType::Empty && complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Empty) {
705  validContentType = true; // 1.4.2
706  } else { // 1.4.3
707  if (complexType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly || complexType->contentType()->variety() == XsdComplexType::ContentType::Mixed) { // 1.4.3.1
708  if (complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Empty) {
709  validContentType = true; // 1.4.3.2.1
710  } else { // 1.4.3.2.2
711  if (complexType->contentType()->particle()) { // our own check
712  if ((complexType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly && complexBaseType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly) ||
713  (complexType->contentType()->variety() == XsdComplexType::ContentType::Mixed && complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Mixed)) { // 1.4.3.2.2.1
714  if (isValidParticleExtension(complexType->contentType()->particle(), complexBaseType->contentType()->particle())) {
715  validContentType = true; // 1.4.3.2.2.2
716  }
717  }
718  }
719  // 1.4.3.2.2.3 and 1.4.3.2.2.4 handle 'open content' that we do not support yet
720  }
721  }
722  }
723 
724  // 1.5 WTF?!?
725 
726  if (!validContentType) {
727  m_context->error(QtXmlPatterns::tr("Content model of complex type %1 is not a valid extension of content model of %2.")
728  .arg(formatType(m_namePool, complexType))
729  .arg(formatType(m_namePool, complexBaseType)),
730  XsdSchemaContext::XSDError, location);
731  return;
732  }
733 
734  } else if (baseType->isSimpleType()) {
735  // 2.1
736  if (complexType->contentType()->variety() != XsdComplexType::ContentType::Simple) {
737  m_context->error(QtXmlPatterns::tr("Complex type %1 must have simple content.")
738  .arg(formatType(m_namePool, complexType)),
739  XsdSchemaContext::XSDError, location);
740  return;
741  }
742 
743  if (complexType->contentType()->simpleType() != baseType) {
744  m_context->error(QtXmlPatterns::tr("Complex type %1 must have the same simple type as its base class %2.")
745  .arg(formatType(m_namePool, complexType))
746  .arg(formatType(m_namePool, baseType)),
747  XsdSchemaContext::XSDError, location);
748  return;
749  }
750 
751  // 2.2 tested in checkInheritanceRestrictions() already
752  }
753  } else if (complexType->derivationMethod() == XsdComplexType::DerivationRestriction) {
754  // @see http://www.w3.org/TR/xmlschema11-1/#d0e21402
755  const SchemaType::Ptr baseType(complexType->wxsSuperType());
756 
757  bool derivationOk = false;
758  QString errorMsg;
759 
760  // we can partly skip 1 here, as it is tested in checkInheritanceRestrictions() already
761  if (baseType->isComplexType()) {
762 
763  // 2.1
764  if (baseType->name(m_namePool) == BuiltinTypes::xsAnyType->name(m_namePool)) {
765  derivationOk = true;
766  }
767 
768  if (baseType->isDefinedBySchema()) {
769  const XsdComplexType::Ptr complexBaseType(baseType);
770 
771  // 2.2.1
772  if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple) {
773  // 2.2.2.1
774  if (XsdSchemaHelper::isSimpleDerivationOk(complexType->contentType()->simpleType(), complexBaseType->contentType()->simpleType(), SchemaType::DerivationConstraints()))
775  derivationOk = true;
776 
777  // 2.2.2.2
778  if (complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Mixed) {
779  if (XsdSchemaHelper::isParticleEmptiable(complexBaseType->contentType()->particle()))
780  derivationOk = true;
781  }
782  }
783 
784  // 2.3.1
785  if (complexType->contentType()->variety() == XsdComplexType::ContentType::Empty) {
786  // 2.3.2.1
787  if (complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Empty)
788  derivationOk = true;
789 
790  // 2.3.2.2
791  if (complexBaseType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly || complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Mixed) {
792  if (XsdSchemaHelper::isParticleEmptiable(complexBaseType->contentType()->particle()))
793  derivationOk = true;
794  }
795  }
796 
797  // 2.4.1.1
798  if (((complexType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly) &&
799  (complexBaseType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly || complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Mixed)) ||
800  // 2.4.1.2
801  (complexType->contentType()->variety() == XsdComplexType::ContentType::Mixed && complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Mixed)) {
802 
803  // 2.4.2
804  if (XsdParticleChecker::subsumes(complexBaseType->contentType()->particle(), complexType->contentType()->particle(), m_context, errorMsg))
805  derivationOk = true;
806  }
807  }
808  }
809 
810  if (!derivationOk) {
811  m_context->error(QtXmlPatterns::tr("Complex type %1 cannot be derived from base type %2%3.")
812  .arg(formatType(m_namePool, complexType))
813  .arg(formatType(m_namePool, baseType))
814  .arg(errorMsg.isEmpty() ? QString() : QLatin1String(": ") + errorMsg),
815  XsdSchemaContext::XSDError, location);
816  return;
817  }
818 
819  if (baseType->isDefinedBySchema()) {
820  const XsdComplexType::Ptr complexBaseType(baseType);
821 
822  QString errorMsg;
823  if (!XsdSchemaHelper::isValidAttributeUsesRestriction(complexType->attributeUses(), complexBaseType->attributeUses(),
824  complexType->attributeWildcard(), complexBaseType->attributeWildcard(), m_context, errorMsg)) {
825  m_context->error(QtXmlPatterns::tr("Attributes of complex type %1 are not a valid restriction from the attributes of base type %2: %3.")
826  .arg(formatType(m_namePool, complexType))
827  .arg(formatType(m_namePool, baseType))
828  .arg(errorMsg),
829  XsdSchemaContext::XSDError, location);
830  return;
831  }
832  }
833  }
834 
835  // check that complex type with simple content is not allowed to inherit from
836  // built in complex type xs:AnyType
837  if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple) {
838  if (baseType->name(m_namePool) == BuiltinTypes::xsAnyType->name(m_namePool)) {
839  m_context->error(QtXmlPatterns::tr("Complex type %1 with simple content cannot be derived from complex base type %2.")
840  .arg(formatType(m_namePool, complexType))
841  .arg(formatType(m_namePool, baseType)),
842  XsdSchemaContext::XSDError, location);
843  return;
844  }
845  }
846  }
847 }
The complex type has further elements or attributes and text as content.
int type
Definition: qmetatype.cpp:239
QExplicitlySharedDataPointer< XsdSchemaContext > m_context
A context for schema parsing and validation.
virtual bool isSimpleType() const
Definition: qschematype.cpp:56
QString formatKeyword(const QString &keyword)
static bool hasDuplicatedElements(const XsdParticle::Ptr &particle, const NamePool::Ptr &namePool, XsdElement::Ptr &conflictingElement)
QString formatType(const NamePool::Ptr &np, const T &type)
Formats ItemType and SequenceType.
QSourceLocation sourceLocation(const NamedSchemaComponent::Ptr &component) const
static bool subsumes(const XsdParticle::Ptr &particle, const XsdParticle::Ptr &derivedParticle, const XsdSchemaContext::Ptr &context, QString &errorMsg)
SchemaType::List anonymousTypes() const
Definition: qxsdschema.cpp:181
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
The QString class provides a Unicode character string.
Definition: qstring.h:83
XsdAttributeUse::List attributeUses() const
ContentType::Ptr contentType() const
XsdWildcard::Ptr attributeWildcard() const
virtual SchemaType::Ptr wxsSuperType() const
static const SchemaType::Ptr xsAnyType
void error(const QString &message, const ReportContext::ErrorCode errorCode, const QSourceLocation &sourceLocation)
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
virtual bool isComplexType() const
Definition: qschematype.cpp:70
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
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)
virtual QString displayName(const NamePool::Ptr &namePool) const
The QSourceLocation class identifies a location in a resource by URI, line, and column.
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal...
Definition: qstring.h:654
static bool isUPAConform(const XsdParticle::Ptr &particle, const NamePool::Ptr &namePool)
static bool isSimpleDerivationOk(const SchemaType::Ptr &derivedType, const SchemaType::Ptr &baseType, const SchemaType::DerivationConstraints &constraints)
The complex type has only simple type content (e.g. text, number etc.)
virtual DerivationMethod derivationMethod() const
static const struct @32 types[]
static QTestResult::TestLocation location
Definition: qtestresult.cpp:63
static bool isParticleEmptiable(const XsdParticle::Ptr &particle)
bool isValidParticleExtension(const XsdParticle::Ptr &extension, const XsdParticle::Ptr &base) const
virtual bool isDefinedBySchema() const
Definition: qschematype.cpp:75
SchemaType::List types() const
Definition: qxsdschema.cpp:131
The complex type has further elements or attributes but no text as content.
The complex type has no further content.
virtual QXmlName name(const NamePool::Ptr &np) const =0
Returns the name of the type.
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)

◆ checkConstrainingFacets() [1/2]

void XsdSchemaChecker::checkConstrainingFacets ( )

Checks the constraining facets of all global and anonymous simple types for validity.

Definition at line 947 of file qxsdschemachecker.cpp.

Referenced by QPatternist::XsdSchemaResolver::resolve().

948 {
949  // first the global simple types
951  for (int i = 0; i < types.count(); ++i) {
952  if (!(types.at(i)->isSimpleType()) || !(types.at(i)->isDefinedBySchema()))
953  continue;
954 
955  const XsdSimpleType::Ptr simpleType = types.at(i);
956  checkConstrainingFacets(simpleType->facets(), simpleType);
957  }
958 
959  // and afterwards all anonymous simple types
960  const SchemaType::List anonymousTypes = m_schema->anonymousTypes();
961  for (int i = 0; i < anonymousTypes.count(); ++i) {
962  if (!(anonymousTypes.at(i)->isSimpleType()) || !(anonymousTypes.at(i)->isDefinedBySchema()))
963  continue;
964 
965  const XsdSimpleType::Ptr simpleType = anonymousTypes.at(i);
966  checkConstrainingFacets(simpleType->facets(), simpleType);
967  }
968 }
virtual bool isSimpleType() const
Definition: qschematype.cpp:56
SchemaType::List anonymousTypes() const
Definition: qxsdschema.cpp:181
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
static const struct @32 types[]
XsdFacet::Hash facets() const
virtual bool isDefinedBySchema() const
Definition: qschematype.cpp:75
SchemaType::List types() const
Definition: qxsdschema.cpp:131

◆ checkConstrainingFacets() [2/2]

void XsdSchemaChecker::checkConstrainingFacets ( const XsdFacet::Hash facets,
const XsdSimpleType::Ptr simpleType 
)
private

Checks the set of constraining facets that belongs to simpleType for validity.

Definition at line 970 of file qxsdschemachecker.cpp.

971 {
972  if (facets.isEmpty())
973  return;
974 
975  SchemaType::Ptr comparableBaseType;
976  if (!simpleType->wxsSuperType()->isDefinedBySchema())
977  comparableBaseType = simpleType->wxsSuperType();
978  else
979  comparableBaseType = simpleType->primitiveType();
980 
981  const XsdSchemaSourceLocationReflection reflection(sourceLocation(simpleType));
982 
983  // start checks
984  if (facets.contains(XsdFacet::Length)) {
985  const XsdFacet::Ptr lengthFacet = facets.value(XsdFacet::Length);
986  const DerivedInteger<TypeNonNegativeInteger>::Ptr lengthValue = lengthFacet->value();
987 
988  // @see http://www.w3.org/TR/xmlschema-2/#length-minLength-maxLength
989  if (facets.contains(XsdFacet::MinimumLength)) {
990  const XsdFacet::Ptr minLengthFacet = facets.value(XsdFacet::MinimumLength);
991  const DerivedInteger<TypeNonNegativeInteger>::Ptr minLengthValue = minLengthFacet->value();
992 
993  bool foundSuperMinimumLength = false;
994  SchemaType::Ptr baseType = simpleType->wxsSuperType();
995  while (baseType) {
996  const XsdFacet::Hash baseFacets = m_context->facetsForType(baseType);
997  if (baseFacets.contains(XsdFacet::MinimumLength) && !baseFacets.contains(XsdFacet::Length)) {
998  const DerivedInteger<TypeNonNegativeInteger>::Ptr superValue(baseFacets.value(XsdFacet::MinimumLength)->value());
999  if (minLengthValue->toInteger() == superValue->toInteger()) {
1000  foundSuperMinimumLength = true;
1001  break;
1002  }
1003  }
1004 
1005  baseType = baseType->wxsSuperType();
1006  }
1007 
1008  if ((minLengthValue->toInteger() > lengthValue->toInteger()) || !foundSuperMinimumLength) {
1009  m_context->error(QtXmlPatterns::tr("%1 facet collides with %2 facet.")
1010  .arg(formatKeyword("length"))
1011  .arg(formatKeyword("minLength")),
1013  return;
1014  }
1015  }
1016 
1017  // @see http://www.w3.org/TR/xmlschema-2/#length-minLength-maxLength
1018  if (facets.contains(XsdFacet::MaximumLength)) {
1019  const XsdFacet::Ptr maxLengthFacet = facets.value(XsdFacet::MaximumLength);
1020  const DerivedInteger<TypeNonNegativeInteger>::Ptr maxLengthValue = maxLengthFacet->value();
1021 
1022  bool foundSuperMaximumLength = false;
1023  SchemaType::Ptr baseType = simpleType->wxsSuperType();
1024  while (baseType) {
1025  const XsdFacet::Hash baseFacets = m_context->facetsForType(baseType);
1026  if (baseFacets.contains(XsdFacet::MaximumLength) && !baseFacets.contains(XsdFacet::Length)) {
1027  const DerivedInteger<TypeNonNegativeInteger>::Ptr superValue(baseFacets.value(XsdFacet::MaximumLength)->value());
1028  if (maxLengthValue->toInteger() == superValue->toInteger()) {
1029  foundSuperMaximumLength = true;
1030  break;
1031  }
1032  }
1033 
1034  baseType = baseType->wxsSuperType();
1035  }
1036 
1037  if ((maxLengthValue->toInteger() < lengthValue->toInteger()) || !foundSuperMaximumLength) {
1038  m_context->error(QtXmlPatterns::tr("%1 facet collides with %2 facet.")
1039  .arg(formatKeyword("length"))
1040  .arg(formatKeyword("maxLength")),
1042  return;
1043  }
1044  }
1045 
1046  // @see http://www.w3.org/TR/xmlschema-2/#length-valid-restriction
1048  const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
1049  if (baseFacets.contains(XsdFacet::Length)) {
1050  const DerivedInteger<TypeNonNegativeInteger>::Ptr baseValue = baseFacets.value(XsdFacet::Length)->value();
1051  if (lengthValue->toInteger() != baseValue->toInteger()) {
1052  m_context->error(QtXmlPatterns::tr("%1 facet must have the same value as %2 facet of base type.")
1053  .arg(formatKeyword("length"))
1054  .arg(formatKeyword("length")),
1056  return;
1057  }
1058  }
1059  }
1060  }
1061 
1062  if (facets.contains(XsdFacet::MinimumLength)) {
1063  const XsdFacet::Ptr minLengthFacet = facets.value(XsdFacet::MinimumLength);
1064  const DerivedInteger<TypeNonNegativeInteger>::Ptr minLengthValue = minLengthFacet->value();
1065 
1066  if (facets.contains(XsdFacet::MaximumLength)) {
1067  const XsdFacet::Ptr maxLengthFacet = facets.value(XsdFacet::MaximumLength);
1068  const DerivedInteger<TypeNonNegativeInteger>::Ptr maxLengthValue = maxLengthFacet->value();
1069 
1070  // @see http://www.w3.org/TR/xmlschema-2/#minLength-less-than-equal-to-maxLength
1071  if (maxLengthValue->toInteger() < minLengthValue->toInteger()) {
1072  m_context->error(QtXmlPatterns::tr("%1 facet collides with %2 facet.")
1073  .arg(formatKeyword("minLength"))
1074  .arg(formatKeyword("maxLength")),
1076  return;
1077  }
1078 
1079  // @see http://www.w3.org/TR/xmlschema-2/#minLength-valid-restriction
1080  //TODO: check parent facets
1081  }
1082 
1083  // @see http://www.w3.org/TR/xmlschema-2/#minLength-valid-restriction
1085  const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
1086  if (baseFacets.contains(XsdFacet::MinimumLength)) {
1087  const DerivedInteger<TypeNonNegativeInteger>::Ptr baseValue = baseFacets.value(XsdFacet::MinimumLength)->value();
1088  if (minLengthValue->toInteger() < baseValue->toInteger()) {
1089  m_context->error(QtXmlPatterns::tr("%1 facet must be equal or greater than %2 facet of base type.")
1090  .arg(formatKeyword("minLength"))
1091  .arg(formatKeyword("minLength")),
1093  return;
1094  }
1095  }
1096  }
1097  }
1098  if (facets.contains(XsdFacet::MaximumLength)) {
1099  const XsdFacet::Ptr maxLengthFacet = facets.value(XsdFacet::MaximumLength);
1100  const DerivedInteger<TypeNonNegativeInteger>::Ptr maxLengthValue = maxLengthFacet->value();
1101 
1102  // @see http://www.w3.org/TR/xmlschema-2/#maxLength-valid-restriction
1104  const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
1105  if (baseFacets.contains(XsdFacet::MaximumLength)) {
1106  const DerivedInteger<TypeNonNegativeInteger>::Ptr baseValue(baseFacets.value(XsdFacet::MaximumLength)->value());
1107  if (maxLengthValue->toInteger() > baseValue->toInteger()) {
1108  m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type.")
1109  .arg(formatKeyword("maxLength"))
1110  .arg(formatKeyword("maxLength")),
1112  return;
1113  }
1114  }
1115  }
1116  }
1117  if (facets.contains(XsdFacet::Pattern)) {
1118  // we keep the patterns in separated facets
1119  // @see http://www.w3.org/TR/xmlschema-2/#src-multiple-patterns
1120 
1121  // @see http://www.w3.org/TR/xmlschema-2/#cvc-pattern-valid
1122  const XsdFacet::Ptr patternFacet = facets.value(XsdFacet::Pattern);
1123  const AtomicValue::List multiValue = patternFacet->multiValue();
1124 
1125  for (int i = 0; i < multiValue.count(); ++i) {
1126  const DerivedString<TypeString>::Ptr value = multiValue.at(i);
1127  const QRegExp exp = PatternPlatform::parsePattern(value->stringValue(), m_context, &reflection);
1128  if (!exp.isValid()) {
1129  m_context->error(QtXmlPatterns::tr("%1 facet contains invalid regular expression").arg(formatKeyword("pattern.")), XsdSchemaContext::XSDError, sourceLocation(simpleType));
1130  return;
1131  }
1132  }
1133  }
1134  if (facets.contains(XsdFacet::Enumeration)) {
1135  // @see http://www.w3.org/TR/xmlschema-2/#src-multiple-enumerations
1136 
1137  const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration);
1138 
1139  if (BuiltinTypes::xsNOTATION->wxsTypeMatches(simpleType)) {
1140  const AtomicValue::List notationNames = facet->multiValue();
1141  for (int k = 0; k < notationNames.count(); ++k) {
1142  const QNameValue::Ptr notationName = notationNames.at(k);
1143  if (!m_schema->notation(notationName->qName())) {
1144  m_context->error(QtXmlPatterns::tr("Unknown notation %1 used in %2 facet.")
1145  .arg(formatKeyword(m_namePool, notationName->qName()))
1146  .arg(formatKeyword("enumeration")),
1148  }
1149  }
1150  } else if (BuiltinTypes::xsQName->wxsTypeMatches(simpleType)) {
1151  } else {
1152  const XsdTypeChecker checker(m_context, QVector<QXmlName>(), sourceLocation(simpleType));
1153 
1154  const AnySimpleType::Ptr baseType = simpleType->wxsSuperType();
1155  const XsdFacet::Hash baseFacets = XsdTypeChecker::mergedFacetsForType(baseType, m_context);
1156 
1157  const AtomicValue::List multiValue = facet->multiValue();
1158  for (int k = 0; k < multiValue.count(); ++k) {
1159  const QString stringValue = multiValue.at(k)->as<DerivedString<TypeString> >()->stringValue();
1160  const QString actualValue = XsdTypeChecker::normalizedValue(stringValue, baseFacets);
1161 
1162  QString errorMsg;
1163  if (!checker.isValidString(actualValue, baseType, errorMsg)) {
1164  m_context->error(QtXmlPatterns::tr("%1 facet contains invalid value %2: %3.")
1165  .arg(formatKeyword("enumeration"))
1166  .arg(formatData(stringValue))
1167  .arg(errorMsg),
1169  return;
1170  }
1171  }
1172  }
1173  }
1174  if (facets.contains(XsdFacet::WhiteSpace)) {
1175  const XsdFacet::Ptr whiteSpaceFacet = facets.value(XsdFacet::WhiteSpace);
1176  const DerivedString<TypeString>::Ptr whiteSpaceValue = whiteSpaceFacet->value();
1177 
1178  // @see http://www.w3.org/TR/xmlschema-2/#whiteSpace-valid-restriction
1180  const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
1181  if (baseFacets.contains(XsdFacet::WhiteSpace)) {
1182  const QString value = whiteSpaceValue->stringValue();
1183  const QString baseValue = DerivedString<TypeString>::Ptr(baseFacets.value(XsdFacet::WhiteSpace)->value())->stringValue();
1186  m_context->error(QtXmlPatterns::tr("%1 facet cannot be %2 or %3 if %4 facet of base type is %5.")
1187  .arg(formatKeyword("whiteSpace"))
1188  .arg(formatData("replace"))
1189  .arg(formatData("preserve"))
1190  .arg(formatKeyword("whiteSpace"))
1191  .arg(formatData("collapse")),
1193  return;
1194  }
1195  }
1197  m_context->error(QtXmlPatterns::tr("%1 facet cannot be %2 if %3 facet of base type is %4.")
1198  .arg(formatKeyword("whiteSpace"))
1199  .arg(formatData("preserve"))
1200  .arg(formatKeyword("whiteSpace"))
1201  .arg(formatData("replace")),
1203  return;
1204  }
1205  }
1206  }
1207  }
1208  if (facets.contains(XsdFacet::MaximumInclusive)) {
1209  const XsdFacet::Ptr maxFacet = facets.value(XsdFacet::MaximumInclusive);
1210 
1211  // @see http://www.w3.org/TR/xmlschema-2/#minInclusive-less-than-equal-to-maxInclusive
1212  if (facets.contains(XsdFacet::MinimumInclusive)) {
1213  const XsdFacet::Ptr minFacet = facets.value(XsdFacet::MinimumInclusive);
1214 
1215  if (comparableBaseType) {
1216  if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterThan, maxFacet->value(), comparableBaseType, m_context, &reflection)) {
1217  m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet.")
1218  .arg(formatKeyword("minInclusive"))
1219  .arg(formatKeyword("maxInclusive")),
1221  return;
1222  }
1223  }
1224  }
1225 
1226  // @see http://www.w3.org/TR/xmlschema-2/#maxInclusive-valid-restriction
1228  const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
1229  if (baseFacets.contains(XsdFacet::MaximumInclusive)) {
1230  const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumInclusive);
1231  if (comparableBaseType) {
1232  if (XsdSchemaHelper::constructAndCompare(maxFacet->value(), AtomicComparator::OperatorGreaterThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
1233  m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type.")
1234  .arg(formatKeyword("maxInclusive"))
1235  .arg(formatKeyword("maxInclusive")),
1237  return;
1238  }
1239  }
1240  }
1241  if (baseFacets.contains(XsdFacet::MaximumExclusive)) {
1242  const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumExclusive);
1243  if (comparableBaseType) {
1244  if (XsdSchemaHelper::constructAndCompare(maxFacet->value(), AtomicComparator::OperatorGreaterOrEqual, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
1245  m_context->error(QtXmlPatterns::tr("%1 facet must be less than %2 facet of base type.")
1246  .arg(formatKeyword("maxInclusive"))
1247  .arg(formatKeyword("maxExclusive")),
1249  return;
1250  }
1251  }
1252  }
1253  }
1254  }
1255  if (facets.contains(XsdFacet::MaximumExclusive)) {
1256  const XsdFacet::Ptr maxFacet = facets.value(XsdFacet::MaximumExclusive);
1257 
1258  // @see http://www.w3.org/TR/xmlschema-2/#maxInclusive-maxExclusive
1259  if (facets.contains(XsdFacet::MaximumInclusive)) {
1260  m_context->error(QtXmlPatterns::tr("%1 facet and %2 facet cannot appear together.")
1261  .arg(formatKeyword("maxExclusive"))
1262  .arg(formatKeyword("maxInclusive")),
1264  return;
1265  }
1266 
1267  // @see http://www.w3.org/TR/xmlschema-2/#minExclusive-less-than-equal-to-maxExclusive
1268  if (facets.contains(XsdFacet::MinimumExclusive)) {
1269  const XsdFacet::Ptr minFacet = facets.value(XsdFacet::MinimumExclusive);
1270  if (comparableBaseType) {
1271  if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterThan, maxFacet->value(), comparableBaseType, m_context, &reflection)) {
1272  m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet.")
1273  .arg(formatKeyword("minExclusive"))
1274  .arg(formatKeyword("maxExclusive")),
1276  return;
1277  }
1278  }
1279  }
1280 
1281  // @see http://www.w3.org/TR/xmlschema-2/#maxExclusive-valid-restriction
1283  const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
1284  if (baseFacets.contains(XsdFacet::MaximumExclusive)) {
1285  const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumExclusive);
1286  if (comparableBaseType) {
1287  if (XsdSchemaHelper::constructAndCompare(maxFacet->value(), AtomicComparator::OperatorGreaterThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
1288  m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type.")
1289  .arg(formatKeyword("maxExclusive"))
1290  .arg(formatKeyword("maxExclusive")),
1292  return;
1293  }
1294  }
1295  }
1296  if (baseFacets.contains(XsdFacet::MaximumInclusive)) {
1297  const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumInclusive);
1298  if (comparableBaseType) {
1299  if (XsdSchemaHelper::constructAndCompare(maxFacet->value(), AtomicComparator::OperatorGreaterThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
1300  m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type.")
1301  .arg(formatKeyword("maxExclusive"))
1302  .arg(formatKeyword("maxInclusive")),
1304  return;
1305  }
1306  }
1307  }
1308  if (baseFacets.contains(XsdFacet::MinimumInclusive)) {
1309  const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MinimumInclusive);
1310  if (comparableBaseType) {
1311  if (XsdSchemaHelper::constructAndCompare(maxFacet->value(), AtomicComparator::OperatorLessOrEqual, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
1312  m_context->error(QtXmlPatterns::tr("%1 facet must be greater than %2 facet of base type.")
1313  .arg(formatKeyword("maxExclusive"))
1314  .arg(formatKeyword("minInclusive")),
1316  return;
1317  }
1318  }
1319  }
1320  if (baseFacets.contains(XsdFacet::MinimumExclusive)) {
1321  const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MinimumExclusive);
1322  if (comparableBaseType) {
1323  if (XsdSchemaHelper::constructAndCompare(maxFacet->value(), AtomicComparator::OperatorLessOrEqual, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
1324  m_context->error(QtXmlPatterns::tr("%1 facet must be greater than %2 facet of base type.")
1325  .arg(formatKeyword("maxExclusive"))
1326  .arg(formatKeyword("minExclusive")),
1328  return;
1329  }
1330  }
1331  }
1332  }
1333  }
1334  if (facets.contains(XsdFacet::MinimumExclusive)) {
1335  const XsdFacet::Ptr minFacet = facets.value(XsdFacet::MinimumExclusive);
1336 
1337  // @see http://www.w3.org/TR/xmlschema-2/#minInclusive-minExclusive
1338  if (facets.contains(XsdFacet::MinimumInclusive)) {
1339  m_context->error(QtXmlPatterns::tr("%1 facet and %2 facet cannot appear together.")
1340  .arg(formatKeyword("minExclusive"))
1341  .arg(formatKeyword("minInclusive")),
1343  return;
1344  }
1345 
1346  // @see http://www.w3.org/TR/xmlschema-2/#minExclusive-less-than-maxInclusive
1347  if (facets.contains(XsdFacet::MaximumInclusive)) {
1348  const XsdFacet::Ptr maxFacet = facets.value(XsdFacet::MaximumInclusive);
1349  if (comparableBaseType) {
1350  if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterOrEqual, maxFacet->value(), comparableBaseType, m_context, &reflection)) {
1351  m_context->error(QtXmlPatterns::tr("%1 facet must be less than %2 facet.")
1352  .arg(formatKeyword("minExclusive"))
1353  .arg(formatKeyword("maxInclusive")),
1355  return;
1356  }
1357  }
1358  }
1359 
1360  // @see http://www.w3.org/TR/xmlschema-2/#minExclusive-valid-restriction
1362  const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
1363  if (baseFacets.contains(XsdFacet::MinimumExclusive)) {
1364  const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MinimumExclusive);
1365  if (comparableBaseType) {
1366  if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorLessThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
1367  m_context->error(QtXmlPatterns::tr("%1 facet must be greater than or equal to %2 facet of base type.")
1368  .arg(formatKeyword("minExclusive"))
1369  .arg(formatKeyword("minExclusive")),
1371  return;
1372  }
1373  }
1374  }
1375  if (baseFacets.contains(XsdFacet::MaximumExclusive)) {
1376  const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumExclusive);
1377  if (comparableBaseType) {
1378  if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterOrEqual, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
1379  m_context->error(QtXmlPatterns::tr("%1 facet must be less than %2 facet of base type.")
1380  .arg(formatKeyword("minExclusive"))
1381  .arg(formatKeyword("maxExclusive")),
1383  return;
1384  }
1385  }
1386  }
1387  if (baseFacets.contains(XsdFacet::MaximumInclusive)) {
1388  const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumInclusive);
1389  if (comparableBaseType) {
1390  if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
1391  m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type.")
1392  .arg(formatKeyword("minExclusive"))
1393  .arg(formatKeyword("maxInclusive")),
1395  return;
1396  }
1397  }
1398  }
1399  }
1400  }
1401  if (facets.contains(XsdFacet::MinimumInclusive)) {
1402  const XsdFacet::Ptr minFacet = facets.value(XsdFacet::MinimumInclusive);
1403 
1404  // @see http://www.w3.org/TR/xmlschema-2/#minInclusive-less-than-maxExclusive
1405  if (facets.contains(XsdFacet::MaximumExclusive)) {
1406  const XsdFacet::Ptr maxFacet = facets.value(XsdFacet::MaximumExclusive);
1407  if (comparableBaseType) {
1408  if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterOrEqual, maxFacet->value(), comparableBaseType, m_context, &reflection)) {
1409  m_context->error(QtXmlPatterns::tr("%1 facet must be less than %2 facet.")
1410  .arg(formatKeyword("minInclusive"))
1411  .arg(formatKeyword("maxExclusive")),
1413  return;
1414  }
1415  }
1416  }
1417 
1418  // @see http://www.w3.org/TR/xmlschema-2/#minInclusive-valid-restriction
1420  const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
1421  if (baseFacets.contains(XsdFacet::MinimumInclusive)) {
1422  const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MinimumInclusive);
1423  if (comparableBaseType) {
1424  if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorLessThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
1425  m_context->error(QtXmlPatterns::tr("%1 facet must be greater than or equal to %2 facet of base type.")
1426  .arg(formatKeyword("minInclusive"))
1427  .arg(formatKeyword("minInclusive")),
1429  return;
1430  }
1431  }
1432  }
1433  if (baseFacets.contains(XsdFacet::MinimumExclusive)) {
1434  const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MinimumExclusive);
1435  if (comparableBaseType) {
1436  if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorLessOrEqual, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
1437  m_context->error(QtXmlPatterns::tr("%1 facet must be greater than %2 facet of base type.")
1438  .arg(formatKeyword("minInclusive"))
1439  .arg(formatKeyword("minExclusive")),
1441  return;
1442  }
1443  }
1444  }
1445  if (baseFacets.contains(XsdFacet::MaximumInclusive)) {
1446  const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumInclusive);
1447  if (comparableBaseType) {
1448  if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
1449  m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type.")
1450  .arg(formatKeyword("minInclusive"))
1451  .arg(formatKeyword("maxInclusive")),
1453  return;
1454  }
1455  }
1456  }
1457  if (baseFacets.contains(XsdFacet::MaximumExclusive)) {
1458  const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumExclusive);
1459  if (comparableBaseType) {
1460  if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterOrEqual, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
1461  m_context->error(QtXmlPatterns::tr("%1 facet must be less than %2 facet of base type.")
1462  .arg(formatKeyword("minInclusive"))
1463  .arg(formatKeyword("maxExclusive")),
1465  return;
1466  }
1467  }
1468  }
1469  }
1470  }
1471  if (facets.contains(XsdFacet::TotalDigits)) {
1472  const XsdFacet::Ptr totalDigitsFacet = facets.value(XsdFacet::TotalDigits);
1473  const DerivedInteger<TypeNonNegativeInteger>::Ptr totalDigitsValue = totalDigitsFacet->value();
1474 
1475  // @see http://www.w3.org/TR/xmlschema-2/#totalDigits-valid-restriction
1477  const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
1478  if (baseFacets.contains(XsdFacet::TotalDigits)) {
1479  const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::TotalDigits);
1480  const DerivedInteger<TypeNonNegativeInteger>::Ptr baseValue = baseFacet->value();
1481 
1482  if (totalDigitsValue->toInteger() > baseValue->toInteger()) {
1483  m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type.")
1484  .arg(formatKeyword("totalDigits"))
1485  .arg(formatKeyword("totalDigits")),
1487  return;
1488  }
1489  }
1490  }
1491  }
1492  if (facets.contains(XsdFacet::FractionDigits)) {
1493  const XsdFacet::Ptr fractionDigitsFacet = facets.value(XsdFacet::FractionDigits);
1494  const DerivedInteger<TypeNonNegativeInteger>::Ptr fractionDigitsValue = fractionDigitsFacet->value();
1495 
1496  // http://www.w3.org/TR/xmlschema-2/#fractionDigits-totalDigits
1497  if (facets.contains(XsdFacet::TotalDigits)) {
1498  const XsdFacet::Ptr totalDigitsFacet = facets.value(XsdFacet::TotalDigits);
1499  const DerivedInteger<TypeNonNegativeInteger>::Ptr totalDigitsValue = totalDigitsFacet->value();
1500 
1501  if (fractionDigitsValue->toInteger() > totalDigitsValue->toInteger()) {
1502  m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet.")
1503  .arg(formatKeyword("fractionDigits"))
1504  .arg(formatKeyword("totalDigits")),
1506  return;
1507  }
1508  }
1509 
1510  // @see http://www.w3.org/TR/xmlschema-2/#fractionDigits-valid-restriction
1512  const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
1513  if (baseFacets.contains(XsdFacet::FractionDigits)) {
1514  const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::FractionDigits);
1515  const DerivedInteger<TypeNonNegativeInteger>::Ptr baseValue = baseFacet->value();
1516 
1517  if (fractionDigitsValue->toInteger() > baseValue->toInteger()) {
1518  m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type.")
1519  .arg(formatKeyword("fractionDigits"))
1520  .arg(formatKeyword("fractionDigits")),
1522  return;
1523  }
1524  }
1525  }
1526  }
1527 
1528 
1529  // check whether facets are allowed for simple types variety
1530  if (simpleType->wxsSuperType()->category() == SchemaType::SimpleTypeAtomic) {
1531  if (simpleType->primitiveType()) {
1532  const QXmlName primitiveTypeName = simpleType->primitiveType()->name(m_namePool);
1533  if (m_allowedAtomicFacets.contains(primitiveTypeName)) {
1534  const QSet<XsdFacet::Type> allowedFacets = m_allowedAtomicFacets.value(primitiveTypeName);
1535  QSet<XsdFacet::Type> availableFacets = facets.keys().toSet();
1536 
1537  if (!availableFacets.subtract(allowedFacets).isEmpty()) {
1538  m_context->error(QtXmlPatterns::tr("Simple type contains not allowed facet %1.")
1539  .arg(formatKeyword(XsdFacet::typeName(availableFacets.toList().first()))),
1541  return;
1542  }
1543  }
1544  }
1545  } else if (simpleType->wxsSuperType()->category() == SchemaType::SimpleTypeList) {
1549  {
1550  m_context->error(QtXmlPatterns::tr("%1, %2, %3, %4, %5 and %6 facets are not allowed when derived by list.")
1551  .arg(formatKeyword("maxInclusive"))
1552  .arg(formatKeyword("maxExclusive"))
1553  .arg(formatKeyword("minInclusive"))
1554  .arg(formatKeyword("minExclusive"))
1555  .arg(formatKeyword("totalDigits"))
1556  .arg(formatKeyword("fractionDigits")),
1558  }
1559  } else if (simpleType->wxsSuperType()->category() == SchemaType::SimpleTypeUnion) {
1565  {
1566  m_context->error(QtXmlPatterns::tr("Only %1 and %2 facets are allowed when derived by union.")
1567  .arg(formatKeyword("pattern"))
1568  .arg(formatKeyword("enumeration")),
1570  }
1571  }
1572 
1573  // check whether value of facet matches the value space of the simple types base type
1574  const SchemaType::Ptr baseType = simpleType->wxsSuperType();
1575  if (!baseType->isDefinedBySchema()) {
1576  const XsdSchemaSourceLocationReflection reflection(sourceLocation(simpleType));
1577 
1578  XsdFacet::HashIterator it(facets);
1579  while (it.hasNext()) {
1580  it.next();
1581  const XsdFacet::Ptr facet = it.value();
1582  if (facet->type() == XsdFacet::MaximumInclusive ||
1583  facet->type() == XsdFacet::MaximumExclusive ||
1584  facet->type() == XsdFacet::MinimumInclusive ||
1585  facet->type() == XsdFacet::MinimumExclusive) {
1586  const DerivedString<TypeString>::Ptr stringValue = facet->value();
1587  const AtomicValue::Ptr value = ValueFactory::fromLexical(stringValue->stringValue(), baseType, m_context, &reflection);
1588  if (value->hasError()) {
1589  m_context->error(QtXmlPatterns::tr("%1 contains %2 facet with invalid data: %3.")
1590  .arg(formatType(m_namePool, simpleType))
1591  .arg(formatKeyword(XsdFacet::typeName(facet->type())))
1592  .arg(formatData(stringValue->stringValue())),
1594  return;
1595  }
1596  }
1597 
1598  // @see http://www.w3.org/TR/xmlschema-2/#enumeration-valid-restriction
1599  if (facet->type() == XsdFacet::Enumeration && baseType != BuiltinTypes::xsNOTATION) {
1600  const AtomicValue::List multiValue = facet->multiValue();
1601  for (int j = 0; j < multiValue.count(); ++j) {
1602  const QString stringValue = DerivedString<TypeString>::Ptr(multiValue.at(j))->stringValue();
1603  const AtomicValue::Ptr value = ValueFactory::fromLexical(stringValue, baseType, m_context, &reflection);
1604  if (value->hasError()) {
1605  m_context->error(QtXmlPatterns::tr("%1 contains %2 facet with invalid data: %3.")
1606  .arg(formatType(m_namePool, simpleType))
1608  .arg(formatData(stringValue)),
1610  return;
1611  }
1612  }
1613  }
1614  }
1615  }
1616 }
virtual DerivationMethod derivationMethod() const
static AtomicValue::Ptr fromLexical(const QString &lexicalValue, const SchemaType::Ptr &type, const ReportContext::Ptr &context, const SourceLocationReflection *const sourceLocationReflection)
Returns an AtomicValue of type type from the lexical space lexicalValue, and raise an error through c...
QExplicitlySharedDataPointer< AtomicValue > Ptr
Definition: qitem_p.h:127
virtual TypeCategory category() const =0
QExplicitlySharedDataPointer< XsdSchemaContext > m_context
Match a minimum inclusive (Minimum Inclusive Definition)
Definition: qxsdfacet_p.h:111
The QRegExp class provides pattern matching using regular expressions.
Definition: qregexp.h:61
QString formatKeyword(const QString &keyword)
virtual bool hasError() const
#define it(className, varName)
static QRegExp parsePattern(const QString &pattern, const ReportContext::Ptr &context, const SourceLocationReflection *const location)
Parses pattern.
QString formatType(const NamePool::Ptr &np, const T &type)
Formats ItemType and SequenceType.
bool isEmpty() const
Definition: qset.h:77
QSourceLocation sourceLocation(const NamedSchemaComponent::Ptr &component) const
static QString typeName(Type type)
Definition: qxsdfacet.cpp:103
virtual xsInteger toInteger() const
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
The QString class provides a Unicode character string.
Definition: qstring.h:83
static QString toString(NodeName token)
static bool constructAndCompare(const DerivedString< TypeString >::Ptr &operand1, const AtomicComparator::Operator op, const DerivedString< TypeString >::Ptr &operand2, const SchemaType::Ptr &type, const ReportContext::Ptr &context, const SourceLocationReflection *const sourceLocationReflection)
bool contains(const Key &key) const
Returns true if the hash contains an item with the key; otherwise returns false.
Definition: qhash.h:872
const T value(const Key &key) const
Returns the value associated with the key.
Definition: qhash.h:606
virtual QXmlName name(const NamePool::Ptr &np) const
Returns the name of the type.
Match a maximum exclusive (Maximum Exclusive Definition)
Definition: qxsdfacet_p.h:110
bool isValid() const
Returns true if the regular expression is valid; otherwise returns false.
Definition: qregexp.cpp:3943
Match an enumeration (Enumeration Definition)
Definition: qxsdfacet_p.h:115
virtual SchemaType::Ptr wxsSuperType() const
const TCastTarget * as() const
void error(const QString &message, const ReportContext::ErrorCode errorCode, const QSourceLocation &sourceLocation)
Match the minimum length (Minimum Length Definition)
Definition: qxsdfacet_p.h:105
static XsdFacet::Hash mergedFacetsForType(const SchemaType::Ptr &type, const XsdSchemaContext::Ptr &context)
QList< T > toList() const
Definition: qset.h:296
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
XsdNotation::Ptr notation(const QXmlName &name) const
Definition: qxsdschema.cpp:237
bool isEmpty() const
Returns true if the hash contains no items; otherwise returns false.
Definition: qhash.h:297
static QString normalizedValue(const QString &value, const XsdFacet::Hash &facets)
static QString formatData(const QString &data)
QSet< T > & subtract(const QSet< T > &other)
Definition: qset.h:270
Match a whitespace rule (White Space Definition)
Definition: qxsdfacet_p.h:108
Match a maximum inclusive (Maximum Inclusive Definition)
Definition: qxsdfacet_p.h:109
Match some double digits (Fraction Digits Definition)
Definition: qxsdfacet_p.h:114
Represents instances of derived xs:string types, such as xs:normalizedString.
Match a minimum exclusive (Minimum Exclusive Definition)
Definition: qxsdfacet_p.h:112
Match some integer digits (Total Digits Definition)
Definition: qxsdfacet_p.h:113
The QXmlName class represents the name of an XML node, in an efficient, namespace-aware way...
Definition: qxmlname.h:58
static const AtomicType::Ptr xsQName
static bool wxsTypeMatches(const SchemaType::Ptr &type, const SchemaType::Ptr &otherType, QSet< SchemaType::Ptr > &visitedTypes, SchemaType::Ptr &conflictingType)
Match the exact length (Length Definition)
Definition: qxsdfacet_p.h:104
An implementation of SourceLocationReflection that takes a QSourceLocation.
Match a regular expression (Pattern Definition)
Definition: qxsdfacet_p.h:107
XsdFacet::Hash facetsForType(const AnySimpleType::Ptr &type) const
AnySimpleType::Ptr primitiveType() const
QHashIterator< XsdFacet::Type, XsdFacet::Ptr > HashIterator
Definition: qxsdfacet_p.h:119
virtual QString stringValue() const
Represents instances of derived xs:integer types, such as xs:byte.
virtual bool isDefinedBySchema() const
Definition: qschematype.cpp:75
QHash< QXmlName, QSet< XsdFacet::Type > > m_allowedAtomicFacets
static const AtomicType::Ptr xsNOTATION
The class that provides methods for checking a string against a type.
virtual SchemaType::Ptr wxsSuperType() const =0
QList< Key > keys() const
Returns a list containing all the keys in the hash, in an arbitrary order.
Definition: qhash.h:648
Match the maximum length (Maximum Length Definition)
Definition: qxsdfacet_p.h:106

◆ checkDuplicatedAttributeUses()

void XsdSchemaChecker::checkDuplicatedAttributeUses ( )
private

Checks for duplicated attribute uses (attributes with the same name) inside a complex type.

Definition at line 1618 of file qxsdschemachecker.cpp.

Referenced by check().

1619 {
1620  // first all global attribute groups
1621  const XsdAttributeGroup::List attributeGroups = m_schema->attributeGroups();
1622  for (int i = 0; i < attributeGroups.count(); ++i) {
1623  const XsdAttributeGroup::Ptr attributeGroup = attributeGroups.at(i);
1624  const XsdAttributeUse::List uses = attributeGroup->attributeUses();
1625 
1626  // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 4)
1627  XsdAttribute::Ptr conflictingAttribute;
1628  if (hasDuplicatedAttributeUses(uses, conflictingAttribute)) {
1629  m_context->error(QtXmlPatterns::tr("Attribute group %1 contains attribute %2 twice.")
1630  .arg(formatKeyword(attributeGroup->displayName(m_namePool)))
1631  .arg(formatKeyword(conflictingAttribute->displayName(m_namePool))),
1632  XsdSchemaContext::XSDError, sourceLocation(attributeGroup));
1633  return;
1634  }
1635 
1636  // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 5)
1637  if (hasMultipleIDAttributeUses(uses)) {
1638  m_context->error(QtXmlPatterns::tr("Attribute group %1 contains two different attributes that both have types derived from %2.")
1639  .arg(formatKeyword(attributeGroup->displayName(m_namePool)))
1641  XsdSchemaContext::XSDError, sourceLocation(attributeGroup));
1642  return;
1643  }
1644 
1645  if (hasConstraintIDAttributeUse(uses, conflictingAttribute)) {
1646  m_context->error(QtXmlPatterns::tr("Attribute group %1 contains attribute %2 that has value constraint but type that inherits from %3.")
1647  .arg(formatKeyword(attributeGroup->displayName(m_namePool)))
1648  .arg(formatKeyword(conflictingAttribute->displayName(m_namePool)))
1650  XsdSchemaContext::XSDError, sourceLocation(attributeGroup));
1651  return;
1652  }
1653  }
1654 
1655  // then the global and anonymous complex types
1657  types << m_schema->anonymousTypes();
1658 
1659  for (int i = 0; i < types.count(); ++i) {
1660  if (!(types.at(i)->isComplexType()) || !types.at(i)->isDefinedBySchema())
1661  continue;
1662 
1663  const XsdComplexType::Ptr complexType = types.at(i);
1664  const XsdAttributeUse::List attributeUses = complexType->attributeUses();
1665 
1666  // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 4)
1667  XsdAttribute::Ptr conflictingAttribute;
1668  if (hasDuplicatedAttributeUses(attributeUses, conflictingAttribute)) {
1669  m_context->error(QtXmlPatterns::tr("Complex type %1 contains attribute %2 twice.")
1670  .arg(formatType(m_namePool, complexType))
1671  .arg(formatKeyword(conflictingAttribute->displayName(m_namePool))),
1673  return;
1674  }
1675 
1676  // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 5)
1677  if (hasMultipleIDAttributeUses(attributeUses)) {
1678  m_context->error(QtXmlPatterns::tr("Complex type %1 contains two different attributes that both have types derived from %2.")
1679  .arg(formatType(m_namePool, complexType))
1682  return;
1683  }
1684 
1685  if (hasConstraintIDAttributeUse(attributeUses, conflictingAttribute)) {
1686  m_context->error(QtXmlPatterns::tr("Complex type %1 contains attribute %2 that has value constraint but type that inherits from %3.")
1687  .arg(formatType(m_namePool, complexType))
1688  .arg(formatKeyword(conflictingAttribute->displayName(m_namePool)))
1691  return;
1692  }
1693  }
1694 }
static const AtomicType::Ptr xsID
QExplicitlySharedDataPointer< XsdSchemaContext > m_context
QString formatKeyword(const QString &keyword)
QString formatType(const NamePool::Ptr &np, const T &type)
Formats ItemType and SequenceType.
QSourceLocation sourceLocation(const NamedSchemaComponent::Ptr &component) const
XsdAttributeUse::List attributeUses() const
SchemaType::List anonymousTypes() const
Definition: qxsdschema.cpp:181
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
bool hasConstraintIDAttributeUse(const XsdAttributeUse::List &list, XsdAttribute::Ptr &conflictingAttribute) const
XsdAttributeUse::List attributeUses() const
void error(const QString &message, const ReportContext::ErrorCode errorCode, const QSourceLocation &sourceLocation)
virtual bool isComplexType() const
Definition: qschematype.cpp:70
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
virtual QString displayName(const NamePool::Ptr &namePool) const
static const struct @32 types[]
bool hasDuplicatedAttributeUses(const XsdAttributeUse::List &list, XsdAttribute::Ptr &conflictingAttribute) const
XsdAttributeGroup::List attributeGroups() const
Definition: qxsdschema.cpp:202
virtual bool isDefinedBySchema() const
Definition: qschematype.cpp:75
SchemaType::List types() const
Definition: qxsdschema.cpp:131
bool hasMultipleIDAttributeUses(const XsdAttributeUse::List &list) const
The QList class is a template class that provides lists.
Definition: qdatastream.h:62

◆ checkElementConstraints()

void XsdSchemaChecker::checkElementConstraints ( )
private

Check the element constraints.

Definition at line 1696 of file qxsdschemachecker.cpp.

Referenced by check().

1697 {
1699  QSetIterator<XsdElement::Ptr> it(elements);
1700  while (it.hasNext()) {
1701  const XsdElement::Ptr element = it.next();
1702 
1703  // @see http://www.w3.org/TR/xmlschema11-1/#e-props-correct
1704 
1705  // 2 and xs:ID check
1706  if (element->valueConstraint()) {
1707  const SchemaType::Ptr type = element->type();
1708 
1709  AnySimpleType::Ptr targetType;
1710  if (type->isSimpleType() && type->category() == SchemaType::SimpleTypeAtomic) {
1711  targetType = type;
1712 
1713  // if it is a XsdSimpleType, use its primitive type as target type
1714  if (type->isDefinedBySchema())
1715  targetType = XsdSimpleType::Ptr(type)->primitiveType();
1716 
1717  } else if (type->isComplexType() && type->isDefinedBySchema()) {
1718  const XsdComplexType::Ptr complexType(type);
1719 
1720  if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple) {
1721  const AnySimpleType::Ptr simpleType = complexType->contentType()->simpleType();
1722  if (simpleType->category() == AnySimpleType::SimpleTypeAtomic) {
1723  targetType = simpleType;
1724 
1725  if (simpleType->isDefinedBySchema())
1726  targetType = XsdSimpleType::Ptr(simpleType)->primitiveType();
1727  }
1728  } else if (complexType->contentType()->variety() != XsdComplexType::ContentType::Mixed) {
1729  m_context->error(QtXmlPatterns::tr("Element %1 is not allowed to have a value constraint if its base type is complex.")
1730  .arg(formatKeyword(element->displayName(m_namePool))),
1732  return;
1733  }
1734  }
1735  if ((targetType == BuiltinTypes::xsID) || BuiltinTypes::xsID->wxsTypeMatches(type)) {
1736  m_context->error(QtXmlPatterns::tr("Element %1 is not allowed to have a value constraint if its type is derived from %2.")
1737  .arg(formatKeyword(element->displayName(m_namePool)))
1740  return;
1741  }
1742 
1743  if (type->isSimpleType()) {
1744  QString errorMsg;
1745  if (!isValidValue(element->valueConstraint()->value(), type, errorMsg)) {
1746  m_context->error(QtXmlPatterns::tr("Value constraint of element %1 is not of elements type: %2.")
1747  .arg(formatKeyword(element->displayName(m_namePool)))
1748  .arg(errorMsg),
1750  return;
1751  }
1752  } else if (type->isComplexType() && type->isDefinedBySchema()) {
1753  const XsdComplexType::Ptr complexType(type);
1754  if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple) {
1755  QString errorMsg;
1756  if (!isValidValue(element->valueConstraint()->value(), complexType->contentType()->simpleType(), errorMsg)) {
1757  m_context->error(QtXmlPatterns::tr("Value constraint of element %1 is not of elements type: %2.")
1758  .arg(formatKeyword(element->displayName(m_namePool)))
1759  .arg(errorMsg),
1761  return;
1762  }
1763  }
1764  }
1765  }
1766 
1767  if (!element->substitutionGroupAffiliations().isEmpty()) {
1768  // 3
1769  if (!element->scope() || element->scope()->variety() != XsdElement::Scope::Global) {
1770  m_context->error(QtXmlPatterns::tr("Element %1 is not allowed to have substitution group affiliation as it is no global element.").arg(formatKeyword(element->displayName(m_namePool))),
1772  return;
1773  }
1774 
1775  // 4
1776  const XsdElement::List affiliations = element->substitutionGroupAffiliations();
1777  for (int i = 0; i < affiliations.count(); ++i) {
1778  const XsdElement::Ptr affiliation = affiliations.at(i);
1779 
1780  bool derivationOk = false;
1781  if (element->type()->isComplexType() && affiliation->type()->isComplexType()) {
1782  if (XsdSchemaHelper::isComplexDerivationOk(element->type(), affiliation->type(), affiliation->substitutionGroupExclusions())) {
1783  derivationOk = true;
1784  }
1785  }
1786  if (element->type()->isComplexType() && affiliation->type()->isSimpleType()) {
1787  if (XsdSchemaHelper::isComplexDerivationOk(element->type(), affiliation->type(), affiliation->substitutionGroupExclusions())) {
1788  derivationOk = true;
1789  }
1790  }
1791  if (element->type()->isSimpleType()) {
1792  if (XsdSchemaHelper::isSimpleDerivationOk(element->type(), affiliation->type(), affiliation->substitutionGroupExclusions())) {
1793  derivationOk = true;
1794  }
1795  }
1796 
1797  if (!derivationOk) {
1798  m_context->error(QtXmlPatterns::tr("Type of element %1 cannot be derived from type of substitution group affiliation.").arg(formatKeyword(element->displayName(m_namePool))),
1800  return;
1801  }
1802  }
1803 
1804  // 5 was checked in XsdSchemaResolver::resolveSubstitutionGroupAffiliations() already
1805  }
1806  }
1807 }
The complex type has further elements or attributes and text as content.
static const AtomicType::Ptr xsID
virtual TypeCategory category() const =0
int type
Definition: qmetatype.cpp:239
QExplicitlySharedDataPointer< XsdSchemaContext > m_context
virtual bool isSimpleType() const
Definition: qschematype.cpp:56
QString formatKeyword(const QString &keyword)
#define it(className, varName)
QString formatType(const NamePool::Ptr &np, const T &type)
Formats ItemType and SequenceType.
QSourceLocation sourceLocation(const NamedSchemaComponent::Ptr &component) const
virtual TypeCategory category() const
bool isValidValue(const QString &value, const AnySimpleType::Ptr &type, QString &errorMsg) const
XsdElement::List substitutionGroupAffiliations() const
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
The QString class provides a Unicode character string.
Definition: qstring.h:83
QSet< XsdElement::Ptr > collectAllElements(const XsdParticle::Ptr &particle)
bool isEmpty() const
Returns true if the list contains no items; otherwise returns false.
Definition: qlist.h:152
SchemaType::Ptr type() const
void error(const QString &message, const ReportContext::ErrorCode errorCode, const QSourceLocation &sourceLocation)
SchemaType::DerivationConstraints substitutionGroupExclusions() const
virtual bool isComplexType() const
Definition: qschematype.cpp:70
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
virtual QString displayName(const NamePool::Ptr &namePool) const
static bool isComplexDerivationOk(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)
The complex type has only simple type content (e.g. text, number etc.)
AnySimpleType::Ptr primitiveType() const
The element is defined globally as child of the schema object.
ValueConstraint::Ptr valueConstraint() const
static const QTextHtmlElement elements[Html_NumElements]
virtual bool isDefinedBySchema() const
Definition: qschematype.cpp:75
Scope::Ptr scope() const

◆ checkElementDuplicates() [1/2]

void XsdSchemaChecker::checkElementDuplicates ( )
private

Check for duplicated elements and element wildcards in all complex type particles.

Definition at line 1956 of file qxsdschemachecker.cpp.

Referenced by checkElementDuplicates().

1957 {
1958  // check all global types...
1960 
1961  // .. and anonymous types
1962  types << m_schema->anonymousTypes();
1963 
1964  for (int i = 0; i < types.count(); ++i) {
1965  const SchemaType::Ptr type = types.at(i);
1966 
1967  if (!type->isComplexType() || !type->isDefinedBySchema())
1968  continue;
1969 
1970  const XsdComplexType::Ptr complexType(type);
1971 
1972  if ((complexType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly) || (complexType->contentType()->variety() == XsdComplexType::ContentType::Mixed)) {
1973  DuplicatedElementMap elementMap;
1974  DuplicatedWildcardMap wildcardMap;
1975 
1976  checkElementDuplicates(complexType->contentType()->particle(), elementMap, wildcardMap);
1977  }
1978  }
1979 }
The complex type has further elements or attributes and text as content.
int type
Definition: qmetatype.cpp:239
QHash< XsdWildcard::NamespaceConstraint::Variety, XsdWildcard::Ptr > DuplicatedWildcardMap
SchemaType::List anonymousTypes() const
Definition: qxsdschema.cpp:181
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
virtual bool isComplexType() const
Definition: qschematype.cpp:70
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
QHash< QXmlName, SchemaType::Ptr > DuplicatedElementMap
static const struct @32 types[]
virtual bool isDefinedBySchema() const
Definition: qschematype.cpp:75
SchemaType::List types() const
Definition: qxsdschema.cpp:131
The complex type has further elements or attributes but no text as content.

◆ checkElementDuplicates() [2/2]

void XsdSchemaChecker::checkElementDuplicates ( const XsdParticle::Ptr particle,
DuplicatedElementMap elementMap,
DuplicatedWildcardMap wildcardMap 
)
private

Check for duplicated elements and element wildcards in the given particle.

Parameters
particleThe particle to check.
elementMapA map to find the duplicated elements.
wildcardMapA map to find the duplicated element wildcards.

Definition at line 1981 of file qxsdschemachecker.cpp.

1982 {
1983  if (particle->term()->isElement()) {
1984  const XsdElement::Ptr element(particle->term());
1985 
1986  if (elementMap.contains(element->name(m_namePool))) {
1987  if (element->type() != elementMap.value(element->name(m_namePool))) {
1988  m_context->error(QtXmlPatterns::tr("Element %1 exists twice with different types.")
1989  .arg(formatKeyword(element->displayName(m_namePool))),
1991  return;
1992  }
1993  } else {
1994  elementMap.insert(element->name(m_namePool), element->type());
1995  }
1996 
1997  // check substitution group affiliation
1998  const XsdElement::List substElements = element->substitutionGroupAffiliations();
1999  for (int i = 0; i < substElements.count(); ++i) {
2000  const XsdElement::Ptr substElement = substElements.at(i);
2001  if (elementMap.contains(substElement->name(m_namePool))) {
2002  if (substElement->type() != elementMap.value(substElement->name(m_namePool))) {
2003  m_context->error(QtXmlPatterns::tr("Element %1 exists twice with different types.")
2004  .arg(formatKeyword(substElement->displayName(m_namePool))),
2006  return;
2007  }
2008  } else {
2009  elementMap.insert(substElement->name(m_namePool), substElement->type());
2010  }
2011  }
2012  } else if (particle->term()->isModelGroup()) {
2013  const XsdModelGroup::Ptr group(particle->term());
2014  const XsdParticle::List particles = group->particles();
2015  for (int i = 0; i < particles.count(); ++i)
2016  checkElementDuplicates(particles.at(i), elementMap, wildcardMap);
2017  } else if (particle->term()->isWildcard()) {
2018  const XsdWildcard::Ptr wildcard(particle->term());
2019 
2020  bool error = false;
2021  if (!wildcardMap.contains(wildcard->namespaceConstraint()->variety())) {
2022  if (!wildcardMap.isEmpty())
2023  error = true;
2024  } else {
2025  const XsdWildcard::Ptr otherWildcard = wildcardMap.value(wildcard->namespaceConstraint()->variety());
2026  if ((wildcard->processContents() != otherWildcard->processContents()) || (wildcard->namespaceConstraint()->namespaces() != otherWildcard->namespaceConstraint()->namespaces()))
2027  error = true;
2028  }
2029 
2030  if (error) {
2031  m_context->error(QtXmlPatterns::tr("Particle contains non-deterministic wildcards."), XsdSchemaContext::XSDError, sourceLocation(wildcard));
2032  return;
2033  } else {
2034  wildcardMap.insert(wildcard->namespaceConstraint()->variety(), wildcard);
2035  }
2036  }
2037 }
QExplicitlySharedDataPointer< XsdSchemaContext > m_context
QString formatKeyword(const QString &keyword)
ProcessContents processContents() const
#define error(msg)
XsdTerm::Ptr term() const
QSourceLocation sourceLocation(const NamedSchemaComponent::Ptr &component) const
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
virtual bool isWildcard() const
Definition: qxsdterm.cpp:58
SchemaType::Ptr type() const
virtual bool isElement() const
Definition: qxsdterm.cpp:48
void error(const QString &message, const ReportContext::ErrorCode errorCode, const QSourceLocation &sourceLocation)
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
virtual QString displayName(const NamePool::Ptr &namePool) const
virtual QXmlName name(const NamePool::Ptr &namePool) const
NamespaceConstraint::Ptr namespaceConstraint() const
virtual bool isModelGroup() const
Definition: qxsdterm.cpp:53

◆ checkInheritanceRestrictions()

void XsdSchemaChecker::checkInheritanceRestrictions ( )
private

Checks for inheritance restrictions given by final or finalDefault attributes.

Definition at line 276 of file qxsdschemachecker.cpp.

Referenced by check().

277 {
278  // check all global types...
280 
281  // .. and anonymous types
282  types << m_schema->anonymousTypes();
283 
284  for (int i = 0; i < types.count(); ++i) {
285  const SchemaType::Ptr type = types.at(i);
287 
288  // check inheritance restrictions given by final property of base class
289  const SchemaType::Ptr baseType = type->wxsSuperType();
290  if (baseType->isDefinedBySchema()) {
292  m_context->error(QtXmlPatterns::tr("%1 is not allowed to derive from %2 by restriction as the latter defines it as final.")
293  .arg(formatType(m_namePool, type))
294  .arg(formatType(m_namePool, baseType)), XsdSchemaContext::XSDError, location);
295  return;
297  m_context->error(QtXmlPatterns::tr("%1 is not allowed to derive from %2 by extension as the latter defines it as final.")
298  .arg(formatType(m_namePool, type))
299  .arg(formatType(m_namePool, baseType)), XsdSchemaContext::XSDError, location);
300  return;
301  }
302  }
303  }
304 }
int type
Definition: qmetatype.cpp:239
QExplicitlySharedDataPointer< XsdSchemaContext > m_context
QString formatType(const NamePool::Ptr &np, const T &type)
Formats ItemType and SequenceType.
SchemaType::List anonymousTypes() const
Definition: qxsdschema.cpp:181
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
void error(const QString &message, const ReportContext::ErrorCode errorCode, const QSourceLocation &sourceLocation)
virtual DerivationConstraints derivationConstraints() const =0
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
The QSourceLocation class identifies a location in a resource by URI, line, and column.
static const struct @32 types[]
static QTestResult::TestLocation location
Definition: qtestresult.cpp:63
virtual DerivationMethod derivationMethod() const =0
virtual bool isDefinedBySchema() const
Definition: qschematype.cpp:75
SchemaType::List types() const
Definition: qxsdschema.cpp:131
QSourceLocation sourceLocationForType(const SchemaType::Ptr &type) const
virtual SchemaType::Ptr wxsSuperType() const =0

◆ checkSimpleDerivationRestrictions()

void XsdSchemaChecker::checkSimpleDerivationRestrictions ( )
private

Checks for list and union derivation restrictions given by final or finalDefault attributes.

Definition at line 849 of file qxsdschemachecker.cpp.

Referenced by check().

850 {
851  // check all global types...
853 
854  // .. and anonymous types
855  types << m_schema->anonymousTypes();
856 
857  for (int i = 0; i < types.count(); ++i) {
858  const SchemaType::Ptr type = types.at(i);
859 
860  if (type->isComplexType())
861  continue;
862 
864  continue;
865 
866  const XsdSimpleType::Ptr simpleType = type;
867  const QSourceLocation location = sourceLocation(simpleType);
868 
869  // check all simple types derived by list
870  if (simpleType->category() == XsdSimpleType::SimpleTypeList) {
871  const AnySimpleType::Ptr itemType = simpleType->itemType();
872 
873  if (itemType->isComplexType()) {
874  m_context->error(QtXmlPatterns::tr("Item type of simple type %1 cannot be a complex type.")
875  .arg(formatType(m_namePool, simpleType)),
876  XsdSchemaContext::XSDError, location);
877  return;
878  }
879 
880 
881  if (itemType->isSimpleType() && itemType->isDefinedBySchema()) {
882  const XsdSimpleType::Ptr simpleItemType = itemType;
883  if (simpleItemType->derivationConstraints() & XsdSimpleType::ListConstraint) {
884  m_context->error(QtXmlPatterns::tr("%1 is not allowed to derive from %2 by list as the latter defines it as final.")
885  .arg(formatType(m_namePool, simpleType))
886  .arg(formatType(m_namePool, simpleItemType)),
887  XsdSchemaContext::XSDError, location);
888  return;
889  }
890  }
891 
892  // @see http://www.w3.org/TR/xmlschema-2/#cos-list-of-atomic
893  if (itemType->category() != SchemaType::SimpleTypeAtomic && itemType->category() != SchemaType::SimpleTypeUnion) {
894  m_context->error(QtXmlPatterns::tr("Variety of item type of %1 must be either atomic or union.").arg(formatType(m_namePool, simpleType)), XsdSchemaContext::XSDError, location);
895  return;
896  }
897 
898  if (itemType->category() == SchemaType::SimpleTypeUnion && itemType->isDefinedBySchema()) {
899  const XsdSimpleType::Ptr simpleItemType = itemType;
900  const AnySimpleType::List memberTypes = simpleItemType->memberTypes();
901  for (int j = 0; j < memberTypes.count(); ++j) {
902  if (memberTypes.at(j)->category() != SchemaType::SimpleTypeAtomic) {
903  m_context->error(QtXmlPatterns::tr("Variety of member types of %1 must be atomic.").arg(formatType(m_namePool, simpleItemType)), XsdSchemaContext::XSDError, location);
904  return;
905  }
906  }
907  }
908  }
909 
910  // check all simple types derived by union
911  if (simpleType->category() == XsdSimpleType::SimpleTypeUnion) {
912  const AnySimpleType::List memberTypes = simpleType->memberTypes();
913 
914  for (int i = 0; i < memberTypes.count(); ++i) {
915  const AnySimpleType::Ptr memberType = memberTypes.at(i);
916 
917  if (memberType->isComplexType()) {
918  m_context->error(QtXmlPatterns::tr("Member type of simple type %1 cannot be a complex type.")
919  .arg(formatType(m_namePool, simpleType)),
920  XsdSchemaContext::XSDError, location);
921  return;
922  }
923 
924  // @see http://www.w3.org/TR/xmlschema-2/#cos-no-circular-unions
925  if (simpleType->name(m_namePool) == memberType->name(m_namePool)) {
926  m_context->error(QtXmlPatterns::tr("%1 is not allowed to have a member type with the same name as itself.")
927  .arg(formatType(m_namePool, simpleType)),
928  XsdSchemaContext::XSDError, location);
929  return;
930  }
931 
932  if (memberType->isSimpleType() && memberType->isDefinedBySchema()) {
933  const XsdSimpleType::Ptr simpleMemberType = memberType;
934  if (simpleMemberType->derivationConstraints() & XsdSimpleType::UnionConstraint) {
935  m_context->error(QtXmlPatterns::tr("%1 is not allowed to derive from %2 by union as the latter defines it as final.")
936  .arg(formatType(m_namePool, simpleType))
937  .arg(formatType(m_namePool, simpleMemberType)),
938  XsdSchemaContext::XSDError, location);
939  return;
940  }
941  }
942  }
943  }
944  }
945 }
virtual TypeCategory category() const =0
int type
Definition: qmetatype.cpp:239
virtual TypeCategory category() const
QExplicitlySharedDataPointer< XsdSchemaContext > m_context
QString formatType(const NamePool::Ptr &np, const T &type)
Formats ItemType and SequenceType.
QSourceLocation sourceLocation(const NamedSchemaComponent::Ptr &component) const
virtual TypeCategory category() const
SchemaType::List anonymousTypes() const
Definition: qxsdschema.cpp:181
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
virtual bool isSimpleType() const
virtual QXmlName name(const NamePool::Ptr &np) const
Returns the name of the type.
void error(const QString &message, const ReportContext::ErrorCode errorCode, const QSourceLocation &sourceLocation)
virtual bool isComplexType() const
Definition: qschematype.cpp:70
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
The QSourceLocation class identifies a location in a resource by URI, line, and column.
static const struct @32 types[]
static QTestResult::TestLocation location
Definition: qtestresult.cpp:63
AnySimpleType::List memberTypes() const
SchemaType::DerivationConstraints derivationConstraints() const
virtual bool isDefinedBySchema() const
Definition: qschematype.cpp:75
SchemaType::List types() const
Definition: qxsdschema.cpp:131
virtual bool isComplexType() const
virtual QXmlName name(const NamePool::Ptr &namePool) const
AnySimpleType::Ptr itemType() const

◆ checkSimpleRestrictionBaseType()

void QPatternist::XsdSchemaChecker::checkSimpleRestrictionBaseType ( )
private

◆ checkSimpleTypeConstraints()

void XsdSchemaChecker::checkSimpleTypeConstraints ( )
private

Definition at line 347 of file qxsdschemachecker.cpp.

Referenced by check().

348 {
349  // check all global types...
351 
352  // .. and anonymous types
353  types << m_schema->anonymousTypes();
354 
355  for (int i = 0; i < types.count(); ++i) {
356  const SchemaType::Ptr type = types.at(i);
357 
358  if (!type->isSimpleType())
359  continue;
360 
361  const XsdSimpleType::Ptr simpleType = type;
362 
363  const QSourceLocation location = sourceLocation(simpleType);
364 
365  if (simpleType->category() == XsdSimpleType::None) {
366  // additional checks
367  // check that no user defined type has xs:AnySimpleType as base type (except xs:AnyAtomicType)
369  if (simpleType->name(m_namePool) != BuiltinTypes::xsAnyAtomicType->name(m_namePool)) {
370  m_context->error(QtXmlPatterns::tr("Simple type %1 is not allowed to have base type %2.")
371  .arg(formatType(m_namePool, simpleType))
372  .arg(formatType(m_namePool, simpleType->wxsSuperType())),
374  return;
375  }
376  }
377  // check that no user defined type has xs:AnyAtomicType as base type
378  if (simpleType->wxsSuperType()->name(m_namePool) == BuiltinTypes::xsAnyAtomicType->name(m_namePool)) {
379  m_context->error(QtXmlPatterns::tr("Simple type %1 is not allowed to have base type %2.")
380  .arg(formatType(m_namePool, simpleType))
381  .arg(formatType(m_namePool, simpleType->wxsSuperType())),
383  return;
384  }
385  }
386 
387  // @see http://www.w3.org/TR/xmlschema11-1/#d0e37310
388  if (simpleType->category() == XsdSimpleType::SimpleTypeAtomic) {
389  // 1.1
390  if ((simpleType->wxsSuperType()->category() != XsdSimpleType::SimpleTypeAtomic) && (simpleType->name(m_namePool) != BuiltinTypes::xsAnyAtomicType->name(m_namePool))) {
391  m_context->error(QtXmlPatterns::tr("Simple type %1 can only have simple atomic type as base type.")
392  .arg(formatType(m_namePool, simpleType)),
393  XsdSchemaContext::XSDError, location);
394  }
395  // 1.2
397  m_context->error(QtXmlPatterns::tr("Simple type %1 cannot derive from %2 as the latter defines restriction as final.")
398  .arg(formatType(m_namePool, simpleType->wxsSuperType()))
399  .arg(formatType(m_namePool, simpleType)),
401  }
402 
403  // 1.3
404  // checked by checkConstrainingFacets already
405  } else if (simpleType->category() == XsdSimpleType::SimpleTypeList) {
406  const AnySimpleType::Ptr itemType = simpleType->itemType();
407 
408  // 2.1 or @see http://www.w3.org/TR/xmlschema-2/#cos-list-of-atomic
409  if (itemType->category() != SchemaType::SimpleTypeAtomic && itemType->category() != SchemaType::SimpleTypeUnion) {
410  m_context->error(QtXmlPatterns::tr("Variety of item type of %1 must be either atomic or union.").arg(formatType(m_namePool, simpleType)), XsdSchemaContext::XSDError, location);
411  return;
412  }
413 
414  // 2.1 second part
415  if (itemType->category() == SchemaType::SimpleTypeUnion && itemType->isDefinedBySchema()) {
416  const XsdSimpleType::Ptr simpleItemType = itemType;
417  const AnySimpleType::List memberTypes = simpleItemType->memberTypes();
418  for (int j = 0; j < memberTypes.count(); ++j) {
419  if (memberTypes.at(j)->category() != SchemaType::SimpleTypeAtomic) {
420  m_context->error(QtXmlPatterns::tr("Variety of member types of %1 must be atomic.").arg(formatType(m_namePool, simpleItemType)), XsdSchemaContext::XSDError, location);
421  return;
422  }
423  }
424  }
425 
426  // 2.2.1
428  if (itemType->isSimpleType() && itemType->isDefinedBySchema()) {
429  const XsdSimpleType::Ptr simpleItemType = itemType;
430 
431  // 2.2.1.1
432  if (simpleItemType->derivationConstraints() & XsdSimpleType::ListConstraint) {
433  m_context->error(QtXmlPatterns::tr("%1 is not allowed to derive from %2 by list as the latter defines it as final.")
434  .arg(formatType(m_namePool, simpleType))
435  .arg(formatType(m_namePool, simpleItemType)), XsdSchemaContext::XSDError, location);
436  return;
437  }
438 
439  // 2.2.1.2
440  const XsdFacet::Hash facets = simpleType->facets();
441  XsdFacet::HashIterator it(facets);
442 
443  bool invalidFacetFound = false;
444  while (it.hasNext()) {
445  it.next();
446  if (it.key() != XsdFacet::WhiteSpace) {
447  invalidFacetFound = true;
448  break;
449  }
450  }
451 
452  if (invalidFacetFound) {
453  m_context->error(QtXmlPatterns::tr("Simple type %1 is only allowed to have %2 facet.")
454  .arg(formatType(m_namePool, simpleType))
455  .arg(formatKeyword("whiteSpace")),
456  XsdSchemaContext::XSDError, location);
457  return;
458  }
459  }
460  } else { // 2.2.2
461  // 2.2.2.1
462  if (simpleType->wxsSuperType()->category() != XsdSimpleType::SimpleTypeList) {
463  m_context->error(QtXmlPatterns::tr("Base type of simple type %1 must have variety of type list.").arg(formatType(m_namePool, simpleType)), XsdSchemaContext::XSDError, location);
464  return;
465  }
466 
467  // 2.2.2.2
469  m_context->error(QtXmlPatterns::tr("Base type of simple type %1 has defined derivation by restriction as final.").arg(formatType(m_namePool, simpleType)), XsdSchemaContext::XSDError, location);
470  return;
471  }
472 
473  // 2.2.2.3
474  if (!XsdSchemaHelper::isSimpleDerivationOk(itemType, XsdSimpleType::Ptr(simpleType->wxsSuperType())->itemType(), SchemaType::DerivationConstraints())) {
475  m_context->error(QtXmlPatterns::tr("Item type of base type does not match item type of %1.").arg(formatType(m_namePool, simpleType)), XsdSchemaContext::XSDError, location);
476  return;
477  }
478 
479  // 2.2.2.4
480  const XsdFacet::Hash facets = simpleType->facets();
481  XsdFacet::HashIterator it(facets);
482 
483  bool invalidFacetFound = false;
484  XsdFacet::Type invalidFacetType = XsdFacet::None;
485  while (it.hasNext()) {
486  it.next();
487  const XsdFacet::Type facetType = it.key();
488  if (facetType != XsdFacet::Length &&
489  facetType != XsdFacet::MinimumLength &&
490  facetType != XsdFacet::MaximumLength &&
491  facetType != XsdFacet::WhiteSpace &&
492  facetType != XsdFacet::Pattern &&
493  facetType != XsdFacet::Enumeration) {
494  invalidFacetType = facetType;
495  invalidFacetFound = true;
496  break;
497  }
498  }
499 
500  if (invalidFacetFound) {
501  m_context->error(QtXmlPatterns::tr("Simple type %1 contains not allowed facet type %2.")
502  .arg(formatType(m_namePool, simpleType))
503  .arg(formatKeyword(XsdFacet::typeName(invalidFacetType))),
504  XsdSchemaContext::XSDError, location);
505  return;
506  }
507 
508  // 2.2.2.5
509  // TODO: check value constraints
510  }
511 
512 
513  } else if (simpleType->category() == XsdSimpleType::SimpleTypeUnion) {
514  const AnySimpleType::List memberTypes = simpleType->memberTypes();
515 
516  if (simpleType->wxsSuperType()->name(m_namePool) == BuiltinTypes::xsAnySimpleType->name(m_namePool)) { // 3.1.1
517  // 3.3.1.1
518  for (int i = 0; i < memberTypes.count(); ++i) {
519  const AnySimpleType::Ptr memberType = memberTypes.at(i);
520 
522  m_context->error(QtXmlPatterns::tr("%1 is not allowed to derive from %2 by union as the latter defines it as final.")
523  .arg(formatType(m_namePool, simpleType))
524  .arg(formatType(m_namePool, memberType)), XsdSchemaContext::XSDError, location);
525  return;
526  }
527  }
528 
529  // 3.3.1.2
530  if (!simpleType->facets().isEmpty()) {
531  m_context->error(QtXmlPatterns::tr("%1 is not allowed to have any facets.")
532  .arg(formatType(m_namePool, simpleType)),
533  XsdSchemaContext::XSDError, location);
534  return;
535  }
536  } else {
537  // 3.1.2.1
538  if (simpleType->wxsSuperType()->category() != SchemaType::SimpleTypeUnion) {
539  m_context->error(QtXmlPatterns::tr("Base type %1 of simple type %2 must have variety of union.")
540  .arg(formatType(m_namePool, simpleType->wxsSuperType()))
541  .arg(formatType(m_namePool, simpleType)),
543  return;
544  }
545 
546  // 3.1.2.2
548  m_context->error(QtXmlPatterns::tr("Base type %1 of simple type %2 is not allowed to have restriction in %3 attribute.")
549  .arg(formatType(m_namePool, simpleType->wxsSuperType()))
550  .arg(formatType(m_namePool, simpleType))
551  .arg(formatAttribute("final")),
553  return;
554  }
555 
556  //3.1.2.3
557  if (simpleType->wxsSuperType()->isDefinedBySchema()) {
558  const XsdSimpleType::Ptr simpleBaseType(simpleType->wxsSuperType());
559 
560  AnySimpleType::List baseMemberTypes = simpleBaseType->memberTypes();
561  for (int i = 0; i < memberTypes.count(); ++i) {
562  const AnySimpleType::Ptr memberType = memberTypes.at(i);
563  const AnySimpleType::Ptr baseMemberType = baseMemberTypes.at(i);
564 
565  if (!XsdSchemaHelper::isSimpleDerivationOk(memberType, baseMemberType, SchemaType::DerivationConstraints())) {
566  m_context->error(QtXmlPatterns::tr("Member type %1 cannot be derived from member type %2 of %3's base type %4.")
567  .arg(formatType(m_namePool, memberType))
568  .arg(formatType(m_namePool, baseMemberType))
569  .arg(formatType(m_namePool, simpleType))
570  .arg(formatType(m_namePool, simpleBaseType)),
571  XsdSchemaContext::XSDError, location);
572  }
573  }
574  }
575 
576  // 3.1.2.4
577  const XsdFacet::Hash facets = simpleType->facets();
578  XsdFacet::HashIterator it(facets);
579 
580  bool invalidFacetFound = false;
581  XsdFacet::Type invalidFacetType = XsdFacet::None;
582  while (it.hasNext()) {
583  it.next();
584  const XsdFacet::Type facetType = it.key();
585  if (facetType != XsdFacet::Pattern &&
586  facetType != XsdFacet::Enumeration) {
587  invalidFacetType = facetType;
588  invalidFacetFound = true;
589  break;
590  }
591  }
592 
593  if (invalidFacetFound) {
594  m_context->error(QtXmlPatterns::tr("Simple type %1 contains not allowed facet type %2.")
595  .arg(formatType(m_namePool, simpleType))
596  .arg(formatKeyword(XsdFacet::typeName(invalidFacetType))),
597  XsdSchemaContext::XSDError, location);
598  return;
599  }
600 
601  // 3.1.2.5
602  // TODO: check value constraints
603  }
604  }
605  }
606 }
virtual DerivationConstraints derivationConstraints() const
Definition: qanytype.cpp:98
virtual TypeCategory category() const =0
int type
Definition: qmetatype.cpp:239
virtual TypeCategory category() const
QExplicitlySharedDataPointer< XsdSchemaContext > m_context
virtual bool isSimpleType() const
Definition: qschematype.cpp:56
QString formatKeyword(const QString &keyword)
#define it(className, varName)
QString formatType(const NamePool::Ptr &np, const T &type)
Formats ItemType and SequenceType.
QSourceLocation sourceLocation(const NamedSchemaComponent::Ptr &component) const
virtual TypeCategory category() const
static QString typeName(Type type)
Definition: qxsdfacet.cpp:103
An invalid facet.
Definition: qxsdfacet_p.h:103
SchemaType::List anonymousTypes() const
Definition: qxsdschema.cpp:181
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
virtual bool isSimpleType() const
Match an enumeration (Enumeration Definition)
Definition: qxsdfacet_p.h:115
virtual SchemaType::Ptr wxsSuperType() const
void error(const QString &message, const ReportContext::ErrorCode errorCode, const QSourceLocation &sourceLocation)
virtual DerivationConstraints derivationConstraints() const =0
Match the minimum length (Minimum Length Definition)
Definition: qxsdfacet_p.h:105
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
bool isEmpty() const
Returns true if the hash contains no items; otherwise returns false.
Definition: qhash.h:297
The QSourceLocation class identifies a location in a resource by URI, line, and column.
static bool isSimpleDerivationOk(const SchemaType::Ptr &derivedType, const SchemaType::Ptr &baseType, const SchemaType::DerivationConstraints &constraints)
Match a whitespace rule (White Space Definition)
Definition: qxsdfacet_p.h:108
static const struct @32 types[]
Match the exact length (Length Definition)
Definition: qxsdfacet_p.h:104
XsdFacet::Hash facets() const
static const SchemaType::Ptr xsAnySimpleType
Match a regular expression (Pattern Definition)
Definition: qxsdfacet_p.h:107
static QTestResult::TestLocation location
Definition: qtestresult.cpp:63
QHashIterator< XsdFacet::Type, XsdFacet::Ptr > HashIterator
Definition: qxsdfacet_p.h:119
AnySimpleType::List memberTypes() const
static const AtomicType::Ptr xsAnyAtomicType
SchemaType::DerivationConstraints derivationConstraints() const
static QString formatAttribute(const QString &attribute)
Formats attribute name.
virtual bool isDefinedBySchema() const
Definition: qschematype.cpp:75
SchemaType::List types() const
Definition: qxsdschema.cpp:131
virtual QXmlName name(const NamePool::Ptr &namePool) const
virtual QXmlName name(const NamePool::Ptr &np) const =0
Returns the name of the type.
Match the maximum length (Maximum Length Definition)
Definition: qxsdfacet_p.h:106
AnySimpleType::Ptr itemType() const

◆ elementSequenceAccepted()

bool XsdSchemaChecker::elementSequenceAccepted ( const XsdModelGroup::Ptr sequence,
const XsdParticle::Ptr particle 
) const
private

Checks whether the sequence of elements is accepted by the given particle.

Definition at line 244 of file qxsdschemachecker_helper.cpp.

245 {
246  // @see http://www.w3.org/TR/xmlschema11-1/#cvc-accept
247 
248  if (particle->term()->isWildcard()) { // 1
249  const XsdWildcard::Ptr wildcard(particle->term());
250 
251  // 1.1
252  if ((unsigned int)sequence->particles().count() < particle->minimumOccurs())
253  return false;
254 
255  // 1.2
256  if (!particle->maximumOccursUnbounded()) {
257  if ((unsigned int)sequence->particles().count() > particle->maximumOccurs())
258  return false;
259  }
260 
261  // 1.3
262  const XsdParticle::List particles(sequence->particles());
263  for (int i = 0; i < particles.count(); ++i) {
264  if (particles.at(i)->term()->isElement()) {
265  if (!XsdSchemaHelper::wildcardAllowsExpandedName(XsdElement::Ptr(particles.at(i)->term())->name(m_namePool), wildcard, m_namePool))
266  return false;
267  }
268  }
269  } else if (particle->term()->isElement()) { // 2
270  const XsdElement::Ptr element(particle->term());
271 
272  // 2.1
273  if ((unsigned int)sequence->particles().count() < particle->minimumOccurs())
274  return false;
275 
276  // 2.2
277  if (!particle->maximumOccursUnbounded()) {
278  if ((unsigned int)sequence->particles().count() > particle->maximumOccurs())
279  return false;
280  }
281 
282  // 2.3
283  const XsdParticle::List particles(sequence->particles());
284  for (int i = 0; i < particles.count(); ++i) {
285  bool isValid = false;
286  if (particles.at(i)->term()->isElement()) {
287  const XsdElement::Ptr seqElement(particles.at(i)->term());
288 
289  // 2.3.1
290  if (element->name(m_namePool) == seqElement->name(m_namePool))
291  isValid = true;
292 
293  // 2.3.2
294  if (element->scope() && element->scope()->variety() == XsdElement::Scope::Global) {
295  if (!(element->disallowedSubstitutions() & NamedSchemaComponent::SubstitutionConstraint)) {
296  //TODO: continue
297  }
298  }
299  }
300  }
301  }
302 
303  return true;
304 }
XsdTerm::Ptr term() const
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
virtual bool isWildcard() const
Definition: qxsdterm.cpp:58
unsigned int maximumOccurs() const
virtual bool isElement() const
Definition: qxsdterm.cpp:48
unsigned int minimumOccurs() const
XsdParticle::List particles() const
const char * name
bool maximumOccursUnbounded() const
The element is defined globally as child of the schema object.
static bool wildcardAllowsExpandedName(const QXmlName &name, const XsdWildcard::Ptr &wildcard, const NamePool::Ptr &namePool)

◆ facetsForType()

XsdFacet::Hash QPatternist::XsdSchemaChecker::facetsForType ( const SchemaType::Ptr type) const
private

Returns the list of facets for the given type.

◆ hasConstraintIDAttributeUse()

bool XsdSchemaChecker::hasConstraintIDAttributeUse ( const XsdAttributeUse::List list,
XsdAttribute::Ptr conflictingAttribute 
) const
private

Returns whether the given list of attribute uses contains an attribute uses that has a type inherited by xs:ID with a value constraint. conflictingAttribute will contain the conflicting attribute in that case.

Definition at line 82 of file qxsdschemachecker_helper.cpp.

Referenced by checkDuplicatedAttributeUses().

83 {
84  const int length = list.count();
85 
86  for (int i = 0; i < length; ++i) {
87  const XsdAttributeUse::Ptr attributeUse(list.at(i));
88  if (BuiltinTypes::xsID->wxsTypeMatches(attributeUse->attribute()->type())) {
89  if (attributeUse->valueConstraint()) {
90  conflictingAttribute = attributeUse->attribute();
91  return true;
92  }
93  }
94  }
95 
96  return false;
97 }
static const AtomicType::Ptr xsID
The QExplicitlySharedDataPointer class represents a pointer to an explicitly shared object...
Definition: qshareddata.h:136
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
static bool wxsTypeMatches(const SchemaType::Ptr &type, const SchemaType::Ptr &otherType, QSet< SchemaType::Ptr > &visitedTypes, SchemaType::Ptr &conflictingType)

◆ hasDuplicatedAttributeUses()

bool XsdSchemaChecker::hasDuplicatedAttributeUses ( const XsdAttributeUse::List list,
XsdAttribute::Ptr conflictingAttribute 
) const
private

Returns whether the given list of attribute uses contains two (or more) attribute uses that point to attributes with the same name. conflictingAttribute will contain the conflicting attribute in that case.

Definition at line 46 of file qxsdschemachecker_helper.cpp.

Referenced by checkDuplicatedAttributeUses().

47 {
48  const int length = list.count();
49 
50  for (int i = 0; i < length; ++i) {
51  for (int j = 0; j < length; ++j) {
52  if (i == j)
53  continue;
54 
55  if (list.at(i)->attribute()->name(m_namePool) == list.at(j)->attribute()->name(m_namePool)) {
56  conflictingAttribute = list.at(i)->attribute();
57  return true;
58  }
59  }
60  }
61 
62  return false;
63 }
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468

◆ hasMultipleIDAttributeUses()

bool XsdSchemaChecker::hasMultipleIDAttributeUses ( const XsdAttributeUse::List list) const
private

Returns whether the given list of attribute uses contains two (or more) attribute uses that have a type inherited by xs:ID.

Definition at line 65 of file qxsdschemachecker_helper.cpp.

Referenced by checkDuplicatedAttributeUses().

66 {
67  const int length = list.count();
68 
69  bool hasIdDerivedAttribute = false;
70  for (int i = 0; i < length; ++i) {
71  if (BuiltinTypes::xsID->wxsTypeMatches(list.at(i)->attribute()->type())) {
72  if (hasIdDerivedAttribute)
73  return true;
74  else
75  hasIdDerivedAttribute = true;
76  }
77  }
78 
79  return false;
80 }
static const AtomicType::Ptr xsID
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
static bool wxsTypeMatches(const SchemaType::Ptr &type, const SchemaType::Ptr &otherType, QSet< SchemaType::Ptr > &visitedTypes, SchemaType::Ptr &conflictingType)

◆ isValidParticleExtension()

bool XsdSchemaChecker::isValidParticleExtension ( const XsdParticle::Ptr extension,
const XsdParticle::Ptr base 
) const
private

Checks whether the extension particle is a valid extension of the base particle.

Definition at line 155 of file qxsdschemachecker_helper.cpp.

Referenced by checkComplexTypeConstraints().

156 {
157  // @see http://www.w3.org/TR/xmlschema11-1/#cos-particle-extend
158 
159  // 1
160  if (extension == base)
161  return true;
162 
163  // 2
164  if (extension->minimumOccurs() == 1 && extension->maximumOccurs() == 1 && extension->maximumOccursUnbounded() == false) {
165  if (extension->term()->isModelGroup()) {
166  const XsdModelGroup::Ptr modelGroup = extension->term();
167  if (modelGroup->compositor() == XsdModelGroup::SequenceCompositor) {
168  if (particleEqualsRecursively(modelGroup->particles().first(), base))
169  return true;
170  }
171  }
172  }
173 
174  // 3
175  if (extension->minimumOccurs() == base->minimumOccurs()) { // 3.1
176  if (extension->term()->isModelGroup() && base->term()->isModelGroup()) {
177  const XsdModelGroup::Ptr extensionGroup(extension->term());
178  const XsdModelGroup::Ptr baseGroup(base->term());
179 
180  if (extensionGroup->compositor() == XsdModelGroup::AllCompositor && baseGroup->compositor() == XsdModelGroup::AllCompositor) {
181  const XsdParticle::List extensionParticles = extensionGroup->particles();
182  const XsdParticle::List baseParticles = baseGroup->particles();
183  for (int i = 0; i < baseParticles.count() && i < extensionParticles.count(); ++i) {
184  if (baseParticles.at(i) != extensionParticles.at(i))
185  return false;
186  }
187  }
188  }
189  }
190 
191  return false;
192 }
XsdTerm::Ptr term() const
The model group contains elements only.
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
static const uint base
Definition: qurl.cpp:268
unsigned int maximumOccurs() const
unsigned int minimumOccurs() const
XsdParticle::List particles() const
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
T & first()
Returns a reference to the first item in the list.
Definition: qlist.h:282
bool maximumOccursUnbounded() const
virtual bool isModelGroup() const
Definition: qxsdterm.cpp:53
bool particleEqualsRecursively(const XsdParticle::Ptr &particle, const XsdParticle::Ptr &otherParticle) const
ModelCompositor compositor() const

◆ isValidValue()

bool XsdSchemaChecker::isValidValue ( const QString value,
const AnySimpleType::Ptr type,
QString errorMsg 
) const
private

Checks that the string value is valid according the value space of type for the given component.

Definition at line 1857 of file qxsdschemachecker.cpp.

Referenced by checkAttributeConstraints(), and checkElementConstraints().

1858 {
1860  return true; // no need to check xs:anyType content
1861 
1863  const QString actualValue = XsdTypeChecker::normalizedValue(stringValue, facets);
1864 
1865  const XsdTypeChecker checker(m_context, QVector<QXmlName>(), QSourceLocation(QUrl(QLatin1String("http://dummy.org")), 1, 1));
1866  return checker.isValidString(actualValue, type, errorMsg);
1867 }
QExplicitlySharedDataPointer< XsdSchemaContext > m_context
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
The QUrl class provides a convenient interface for working with URLs.
Definition: qurl.h:61
The QString class provides a Unicode character string.
Definition: qstring.h:83
virtual QXmlName name(const NamePool::Ptr &np) const
Returns the name of the type.
static XsdFacet::Hash mergedFacetsForType(const SchemaType::Ptr &type, const XsdSchemaContext::Ptr &context)
const char * name
The QSourceLocation class identifies a location in a resource by URI, line, and column.
static QString normalizedValue(const QString &value, const XsdFacet::Hash &facets)
static const SchemaType::Ptr xsAnySimpleType
The class that provides methods for checking a string against a type.

◆ particleEqualsRecursively()

bool XsdSchemaChecker::particleEqualsRecursively ( const XsdParticle::Ptr particle,
const XsdParticle::Ptr otherParticle 
) const
private

Checks whether the particle equals the otherParticle recursively.

Definition at line 99 of file qxsdschemachecker_helper.cpp.

Referenced by isValidParticleExtension().

100 {
101  // @see http://www.w3.org/TR/xmlschema11-1/#cos-particle-extend
102  //TODO: find out what 'properties' of a particle should be checked here...
103 
104  if (particle->minimumOccurs() != otherParticle->minimumOccurs())
105  return false;
106 
107  if (particle->maximumOccursUnbounded() != otherParticle->maximumOccursUnbounded())
108  return false;
109 
110  if (particle->maximumOccurs() != otherParticle->maximumOccurs())
111  return false;
112 
113  const XsdTerm::Ptr term = particle->term();
114  const XsdTerm::Ptr otherTerm = otherParticle->term();
115 
116  if (term->isElement() && !(otherTerm->isElement()))
117  return false;
118 
119  if (term->isModelGroup() && !(otherTerm->isModelGroup()))
120  return false;
121 
122  if (term->isWildcard() && !(otherTerm->isWildcard()))
123  return false;
124 
125  if (term->isElement()) {
126  const XsdElement::Ptr element = term;
127  const XsdElement::Ptr otherElement = otherTerm;
128 
129  if (element->name(m_namePool) != otherElement->name(m_namePool))
130  return false;
131 
132  if (element->type()->name(m_namePool) != otherElement->type()->name(m_namePool))
133  return false;
134  }
135 
136  if (term->isModelGroup()) {
137  const XsdModelGroup::Ptr group = term;
138  const XsdModelGroup::Ptr otherGroup = otherTerm;
139 
140  if (group->particles().count() != otherGroup->particles().count())
141  return false;
142 
143  for (int i = 0; i < group->particles().count(); ++i) {
144  if (!particleEqualsRecursively(group->particles().at(i), otherGroup->particles().at(i)))
145  return false;
146  }
147  }
148 
149  if (term->isWildcard()) {
150  }
151 
152  return true;
153 }
XsdTerm::Ptr term() const
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
virtual bool isWildcard() const
Definition: qxsdterm.cpp:58
SchemaType::Ptr type() const
unsigned int maximumOccurs() const
virtual bool isElement() const
Definition: qxsdterm.cpp:48
unsigned int minimumOccurs() const
XsdParticle::List particles() const
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
virtual QXmlName name(const NamePool::Ptr &namePool) const
bool maximumOccursUnbounded() const
virtual bool isModelGroup() const
Definition: qxsdterm.cpp:53
bool particleEqualsRecursively(const XsdParticle::Ptr &particle, const XsdParticle::Ptr &otherParticle) const
virtual QXmlName name(const NamePool::Ptr &np) const =0
Returns the name of the type.

◆ setupAllowedAtomicFacets()

void XsdSchemaChecker::setupAllowedAtomicFacets ( )
private

Setup fast lookup list for allowed facets of atomic simple types.

Definition at line 48 of file qxsdschemachecker_setup.cpp.

Referenced by XsdSchemaChecker().

49 {
50  // string
51  {
52  QSet<XsdFacet::Type> facets;
53  facets << XsdFacet::Length
60 
62  }
63 
64  // boolean
65  {
66  QSet<XsdFacet::Type> facets;
67  facets << XsdFacet::Pattern
70 
72  }
73 
74  // float
75  {
76  QSet<XsdFacet::Type> facets;
77  facets << XsdFacet::Pattern
85 
87  }
88 
89  // double
90  {
91  QSet<XsdFacet::Type> facets;
92  facets << XsdFacet::Pattern
100 
102  }
103 
104  // decimal
105  {
106  QSet<XsdFacet::Type> facets;
107  facets << XsdFacet::TotalDigits
117 
119  }
120 
121  // duration
122  {
123  QSet<XsdFacet::Type> facets;
124  facets << XsdFacet::Pattern
132 
134  }
135 
136  // dateTime
137  {
138  QSet<XsdFacet::Type> facets;
139  facets << XsdFacet::Pattern
147 
149  }
150 
151  // time
152  {
153  QSet<XsdFacet::Type> facets;
154  facets << XsdFacet::Pattern
162 
164  }
165 
166  // date
167  {
168  QSet<XsdFacet::Type> facets;
169  facets << XsdFacet::Pattern
177 
179  }
180 
181  // gYearMonth
182  {
183  QSet<XsdFacet::Type> facets;
184  facets << XsdFacet::Pattern
192 
194  }
195 
196  // gYear
197  {
198  QSet<XsdFacet::Type> facets;
199  facets << XsdFacet::Pattern
207 
209  }
210 
211  // gMonthDay
212  {
213  QSet<XsdFacet::Type> facets;
214  facets << XsdFacet::Pattern
222 
224  }
225 
226  // gDay
227  {
228  QSet<XsdFacet::Type> facets;
229  facets << XsdFacet::Pattern
237 
239  }
240 
241  // gMonth
242  {
243  QSet<XsdFacet::Type> facets;
244  facets << XsdFacet::Pattern
252 
254  }
255 
256  // hexBinary
257  {
258  QSet<XsdFacet::Type> facets;
259  facets << XsdFacet::Length
266 
268  }
269 
270  // base64Binary
271  {
272  QSet<XsdFacet::Type> facets;
273  facets << XsdFacet::Length
280 
282  }
283 
284  // anyURI
285  {
286  QSet<XsdFacet::Type> facets;
287  facets << XsdFacet::Length
294 
296  }
297 
298  // QName
299  {
300  QSet<XsdFacet::Type> facets;
301  facets << XsdFacet::Length
308 
310  }
311 
312  // NOTATION
313  {
314  QSet<XsdFacet::Type> facets;
315  facets << XsdFacet::Length
322 
324  }
325 }
Match an assertion (Assertion Definition)
Definition: qxsdfacet_p.h:116
static const AtomicType::Ptr xsBase64Binary
Match a minimum inclusive (Minimum Inclusive Definition)
Definition: qxsdfacet_p.h:111
static const AtomicType::Ptr xsDuration
static const AtomicType::Ptr xsGYearMonth
static const AtomicType::Ptr xsGMonthDay
Match a maximum exclusive (Maximum Exclusive Definition)
Definition: qxsdfacet_p.h:110
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition: qhash.h:753
static const AtomicType::Ptr xsString
Match an enumeration (Enumeration Definition)
Definition: qxsdfacet_p.h:115
static const AtomicType::Ptr xsGDay
Match the minimum length (Minimum Length Definition)
Definition: qxsdfacet_p.h:105
static const AtomicType::Ptr xsDateTime
const char * name
static const AtomicType::Ptr xsDouble
static const AtomicType::Ptr xsGYear
Match a whitespace rule (White Space Definition)
Definition: qxsdfacet_p.h:108
Match a maximum inclusive (Maximum Inclusive Definition)
Definition: qxsdfacet_p.h:109
Match some double digits (Fraction Digits Definition)
Definition: qxsdfacet_p.h:114
Match a minimum exclusive (Minimum Exclusive Definition)
Definition: qxsdfacet_p.h:112
Match some integer digits (Total Digits Definition)
Definition: qxsdfacet_p.h:113
static const AtomicType::Ptr xsQName
Match the exact length (Length Definition)
Definition: qxsdfacet_p.h:104
Match a regular expression (Pattern Definition)
Definition: qxsdfacet_p.h:107
static const AtomicType::Ptr xsFloat
static const AtomicType::Ptr xsTime
static const AtomicType::Ptr xsDecimal
static const AtomicType::Ptr xsBoolean
static const AtomicType::Ptr xsDate
QHash< QXmlName, QSet< XsdFacet::Type > > m_allowedAtomicFacets
static const AtomicType::Ptr xsNOTATION
static const AtomicType::Ptr xsGMonth
static const AtomicType::Ptr xsHexBinary
static const AtomicType::Ptr xsAnyURI
Match the maximum length (Maximum Length Definition)
Definition: qxsdfacet_p.h:106

◆ sourceLocation()

QSourceLocation XsdSchemaChecker::sourceLocation ( const NamedSchemaComponent::Ptr component) const
private

Returns the source location of the given schema component or a dummy source location if the component is not found in the component location hash.

Definition at line 2039 of file qxsdschemachecker.cpp.

Referenced by checkAttributeConstraints(), checkAttributeUseConstraints(), checkBasicComplexTypeConstraints(), checkBasicSimpleTypeConstraints(), checkComplexTypeConstraints(), checkConstrainingFacets(), checkDuplicatedAttributeUses(), checkElementConstraints(), checkElementDuplicates(), checkSimpleDerivationRestrictions(), checkSimpleTypeConstraints(), and sourceLocationForType().

2040 {
2041  if (m_componentLocationHash.contains(component)) {
2042  return m_componentLocationHash.value(component);
2043  } else {
2045  location.setLine(1);
2046  location.setColumn(1);
2047  location.setUri(QString::fromLatin1("dummyUri"));
2048 
2049  return location;
2050  }
2051 }
void setUri(const QUrl &newUri)
Sets the URI to newUri.
void setLine(qint64 newLine)
Sets the line number to newLine.
bool contains(const Key &key) const
Returns true if the hash contains an item with the key; otherwise returns false.
Definition: qhash.h:872
const T value(const Key &key) const
Returns the value associated with the key.
Definition: qhash.h:606
void setColumn(qint64 newColumn)
Sets the column number to newColumn.
The QSourceLocation class identifies a location in a resource by URI, line, and column.
static QString fromLatin1(const char *, int size=-1)
Returns a QString initialized with the first size characters of the Latin-1 string str...
Definition: qstring.cpp:4188
static QTestResult::TestLocation location
Definition: qtestresult.cpp:63
QHash< NamedSchemaComponent::Ptr, QSourceLocation > m_componentLocationHash

◆ sourceLocationForType()

QSourceLocation XsdSchemaChecker::sourceLocationForType ( const SchemaType::Ptr type) const
private

Returns the source location of the given schema type or a dummy source location if the type is not found in the component location hash.

Definition at line 2053 of file qxsdschemachecker.cpp.

Referenced by checkBasicCircularInheritances(), checkCircularInheritances(), and checkInheritanceRestrictions().

2054 {
2055  if (type->isSimpleType())
2056  return sourceLocation(XsdSimpleType::Ptr(type));
2057  else
2058  return sourceLocation(XsdComplexType::Ptr(type));
2059 }
virtual bool isSimpleType() const
Definition: qschematype.cpp:56
QSourceLocation sourceLocation(const NamedSchemaComponent::Ptr &component) const

Properties

◆ m_allowedAtomicFacets

QHash<QXmlName, QSet<XsdFacet::Type> > QPatternist::XsdSchemaChecker::m_allowedAtomicFacets
private

Definition at line 275 of file qxsdschemachecker_p.h.

Referenced by checkConstrainingFacets(), and setupAllowedAtomicFacets().

◆ m_componentLocationHash

QHash<NamedSchemaComponent::Ptr, QSourceLocation> QPatternist::XsdSchemaChecker::m_componentLocationHash
private

Definition at line 276 of file qxsdschemachecker_p.h.

Referenced by addComponentLocationHash(), and sourceLocation().

◆ m_context

QExplicitlySharedDataPointer<XsdSchemaContext> QPatternist::XsdSchemaChecker::m_context
private

◆ m_namePool

NamePool::Ptr QPatternist::XsdSchemaChecker::m_namePool
private

◆ m_schema

XsdSchema::Ptr QPatternist::XsdSchemaChecker::m_schema
private

The documentation for this class was generated from the following files: