Qt 4.8
qxsdschemachecker.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtXmlPatterns module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qxsdschemachecker_p.h"
43 
44 #include "qderivedinteger_p.h"
45 #include "qderivedstring_p.h"
46 #include "qpatternplatform_p.h"
47 #include "qqnamevalue_p.h"
49 #include "qvaluefactory_p.h"
51 #include "qxsdparticlechecker_p.h"
52 #include "qxsdreference_p.h"
53 #include "qxsdschemacontext_p.h"
54 #include "qxsdschemahelper_p.h"
57 #include "qxsdtypechecker_p.h"
58 
60 
62 
63 using namespace QPatternist;
64 
66  : m_context(context)
67  , m_namePool(parserContext->namePool())
68  , m_schema(parserContext->schema())
69 {
71 }
72 
74 {
75 }
76 
77 /*
78  * This method is called after the resolver has set the base type for every
79  * type and information about deriavtion and 'is simple type vs. is complex type'
80  * are available.
81  */
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 }
92 
94 {
101 
105 // checkElementDuplicates();
106 }
107 
109 {
111 }
112 
117 static bool matchesType(const SchemaType::Ptr &myType, const SchemaType::Ptr &otherType, QSet<SchemaType::Ptr> visitedTypes)
118 {
119  bool retval = false;
120 
121  if (otherType) {
122  if (visitedTypes.contains(otherType)) {
123  return true;
124  } else {
125  visitedTypes.insert(otherType);
126  }
127  // simple types can have different varieties, so we have to check each of them
128  if (otherType->isSimpleType()) {
129  const XsdSimpleType::Ptr simpleType = otherType;
130  if (simpleType->category() == XsdSimpleType::SimpleTypeAtomic) {
131  // for atomic type we use the same test as in SchemaType::wxsTypeMatches
132  retval = (myType == simpleType ? true : matchesType(myType, simpleType->wxsSuperType(), visitedTypes));
133  } else if (simpleType->category() == XsdSimpleType::SimpleTypeList) {
134  // for list type we test against the itemType property
135  retval = (myType == simpleType->itemType() ? true : matchesType(myType, simpleType->itemType()->wxsSuperType(), visitedTypes));
136  } else if (simpleType->category() == XsdSimpleType::SimpleTypeUnion) {
137  // for union type we test against each member type
138  const XsdSimpleType::List members = simpleType->memberTypes();
139  for (int i = 0; i < members.count(); ++i) {
140  if (myType == members.at(i) ? true : matchesType(myType, members.at(i)->wxsSuperType(), visitedTypes)) {
141  retval = true;
142  break;
143  }
144  }
145  } else {
146  // reached xsAnySimple type whichs category is None
147  retval = false;
148  }
149  } else {
150  // if no simple type we handle it like in SchemaType::wxsTypeMatches
151  retval = (myType == otherType ? true : matchesType(myType, otherType->wxsSuperType(), visitedTypes));
152  }
153  } else // if otherType is null it doesn't match
154  retval = false;
155 
156  return retval;
157 }
158 
162 static bool hasCircularUnionInheritance(const XsdSimpleType::Ptr &type, const SchemaType::Ptr &otherType, NamePool::Ptr &namePool)
163 {
164  if (type == otherType) {
165  return true;
166  }
167 
168  if (!otherType->isSimpleType() || !otherType->isDefinedBySchema()) {
169  return false;
170  }
171 
172  const XsdSimpleType::Ptr simpleOtherType = otherType;
173 
174  if (simpleOtherType->category() == XsdSimpleType::SimpleTypeUnion) {
175  const XsdSimpleType::List memberTypes = simpleOtherType->memberTypes();
176  for (int i = 0; i < memberTypes.count(); ++i) {
177  if (otherType->wxsSuperType() == type) {
178  return true;
179  }
180  if (hasCircularUnionInheritance(type, memberTypes.at(i), namePool)) {
181  return true;
182  }
183  }
184  }
185 
186  return false;
187 }
188 
189 static inline bool wxsTypeMatches(const SchemaType::Ptr &type, const SchemaType::Ptr &otherType, QSet<SchemaType::Ptr> &visitedTypes, SchemaType::Ptr &conflictingType)
190 {
191  if (!otherType)
192  return false;
193 
194  if (visitedTypes.contains(otherType)) { // inheritance loop detected
195  conflictingType = otherType;
196  return true;
197  } else {
198  visitedTypes.insert(otherType);
199  }
200 
201  if (type == otherType)
202  return true;
203 
204  return wxsTypeMatches(type, otherType->wxsSuperType(), visitedTypes, conflictingType);
205 }
206 
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 }
238 
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 }
275 
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 }
305 
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 }
346 
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 }
607 
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 }
639 
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 }
848 
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 }
946 
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 }
969 
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 }
1617 
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 }
1695 
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 }
1808 
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 }
1856 
1857 bool XsdSchemaChecker::isValidValue(const QString &stringValue, const AnySimpleType::Ptr &type, QString &errorMsg) const
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 }
1868 
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 }
1955 
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 }
1980 
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 }
2038 
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 }
2052 
2054 {
2055  if (type->isSimpleType())
2056  return sourceLocation(XsdSimpleType::Ptr(type));
2057  else
2058  return sourceLocation(XsdComplexType::Ptr(type));
2059 }
2060 
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...
static uint hash(const uchar *p, int n)
Definition: qhash.cpp:68
The complex type has further elements or attributes and text as content.
static const AtomicType::Ptr xsID
void addComponentLocationHash(const QHash< NamedSchemaComponent::Ptr, QSourceLocation > &hash)
QExplicitlySharedDataPointer< AtomicValue > Ptr
Definition: qitem_p.h:127
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 SchemaType::Ptr wxsSuperType() const
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
Match a minimum inclusive (Minimum Inclusive Definition)
Definition: qxsdfacet_p.h:111
virtual bool isSimpleType() const
Definition: qschematype.cpp:56
The attribute has a default value set.
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)
ProcessContents processContents() const
The attribute use has a fixed value set.
static QRegExp parsePattern(const QString &pattern, const ReportContext::Ptr &context, const SourceLocationReflection *const location)
Parses pattern.
static bool hasDuplicatedElements(const XsdParticle::Ptr &particle, const NamePool::Ptr &namePool, XsdElement::Ptr &conflictingElement)
#define error(msg)
QString formatType(const NamePool::Ptr &np, const T &type)
Formats ItemType and SequenceType.
XsdTerm::Ptr term() const
bool isEmpty() const
Definition: qset.h:77
QSourceLocation sourceLocation(const NamedSchemaComponent::Ptr &component) const
virtual TypeCategory category() const
ValueConstraint::Ptr valueConstraint() const
bool isValidValue(const QString &value, const AnySimpleType::Ptr &type, QString &errorMsg) const
static bool subsumes(const XsdParticle::Ptr &particle, const XsdParticle::Ptr &derivedParticle, const XsdSchemaContext::Ptr &context, QString &errorMsg)
The attribute is not allowed to be there.
void setUri(const QUrl &newUri)
Sets the URI to newUri.
static QString typeName(Type type)
Definition: qxsdfacet.cpp:103
The attribute can be there but doesn&#39;t need to.
An invalid facet.
Definition: qxsdfacet_p.h:103
XsdAttributeUse::List attributeUses() const
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
void setLine(qint64 newLine)
Sets the line number to newLine.
SchemaType::List anonymousTypes() const
Definition: qxsdschema.cpp:181
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 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
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)
XsdSchemaChecker(const QExplicitlySharedDataPointer< XsdSchemaContext > &context, const XsdSchemaParserContext *parserContext)
virtual bool isWildcard() const
Definition: qxsdterm.cpp:58
virtual bool isSimpleType() const
QSet< XsdElement::Ptr > collectAllElements(const XsdParticle::Ptr &particle)
static bool matchesType(const SchemaType::Ptr &myType, const SchemaType::Ptr &otherType, QSet< SchemaType::Ptr > visitedTypes)
bool contains(const Key &key) const
Returns true if the hash contains an item with the key; otherwise returns false.
Definition: qhash.h:872
bool hasConstraintIDAttributeUse(const XsdAttributeUse::List &list, XsdAttribute::Ptr &conflictingAttribute) const
const T value(const Key &key) const
Returns the value associated with the key.
Definition: qhash.h:606
XsdAttributeUse::List attributeUses() const
virtual QXmlName name(const NamePool::Ptr &np) const
Returns the name of the type.
ContentType::Ptr contentType() const
Match a maximum exclusive (Maximum Exclusive Definition)
Definition: qxsdfacet_p.h:110
bool isEmpty() const
Returns true if the list contains no items; otherwise returns false.
Definition: qlist.h:152
XsdWildcard::Ptr attributeWildcard() const
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition: qhash.h:753
SchemaType::Ptr type() const
bool isValid() const
Returns true if the regular expression is valid; otherwise returns false.
Definition: qregexp.cpp:3943
virtual SchemaType::Ptr wxsSuperType() const
Match an enumeration (Enumeration Definition)
Definition: qxsdfacet_p.h:115
static const SchemaType::Ptr xsAnyType
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
virtual bool isElement() const
Definition: qxsdterm.cpp:48
virtual SchemaType::Ptr wxsSuperType() const
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
const TCastTarget * as() 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
static bool checkWildcardProcessContents(const XsdWildcard::Ptr &baseWildcard, const XsdWildcard::Ptr &derivedWildcard)
static XsdFacet::Hash mergedFacetsForType(const SchemaType::Ptr &type, const XsdSchemaContext::Ptr &context)
SchemaType::DerivationConstraints substitutionGroupExclusions() const
bool contains(const T &value) const
Definition: qset.h:91
void setColumn(qint64 newColumn)
Sets the column number to newColumn.
QList< T > toList() const
Definition: qset.h:296
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
AnySimpleType::Ptr type() const
virtual bool isComplexType() const
Definition: qschematype.cpp:70
const char * name
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
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)
The namespace for the internal API of QtXmlPatterns.
virtual QString displayName(const NamePool::Ptr &namePool) const
bool isEmpty() const
Returns true if the hash contains no items; otherwise returns false.
Definition: qhash.h:297
const_iterator insert(const T &value)
Definition: qset.h:179
The QSourceLocation class identifies a location in a resource by URI, line, and column.
virtual QString stringValue() const =0
static bool isComplexDerivationOk(const SchemaType::Ptr &derivedType, const SchemaType::Ptr &baseType, const SchemaType::DerivationConstraints &constraints)
static QString normalizedValue(const QString &value, const XsdFacet::Hash &facets)
static bool isUPAConform(const XsdParticle::Ptr &particle, const NamePool::Ptr &namePool)
bool isValidString(const QString &normalizedString, const AnySimpleType::Ptr &type, QString &errorMsg, AnySimpleType::Ptr *boundType=0) const
static qreal component(const QPointF &point, unsigned int i)
static QString formatData(const QString &data)
QSet< T > & subtract(const QSet< T > &other)
Definition: qset.h:270
virtual QXmlName name(const NamePool::Ptr &namePool) const
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
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.
The complex type has only simple type content (e.g. text, number etc.)
Match a minimum exclusive (Minimum Exclusive Definition)
Definition: qxsdfacet_p.h:112
Match some integer digits (Total Digits Definition)
Definition: qxsdfacet_p.h:113
virtual DerivationMethod derivationMethod() const
bool valuesAreEqual(const QString &value, const QString &otherValue, const AnySimpleType::Ptr &type) const
NamespaceConstraint::Ptr namespaceConstraint() const
The QXmlName class represents the name of an XML node, in an efficient, namespace-aware way...
Definition: qxmlname.h:58
QList< AnySimpleType::Ptr > List
static const AtomicType::Ptr xsQName
static const struct @32 types[]
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
XsdFacet::Hash facets() const
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
An implementation of SourceLocationReflection that takes a QSourceLocation.
static const SchemaType::Ptr xsAnySimpleType
Match a regular expression (Pattern Definition)
Definition: qxsdfacet_p.h:107
static QTestResult::TestLocation location
Definition: qtestresult.cpp:63
XsdFacet::Hash facetsForType(const AnySimpleType::Ptr &type) const
QHash< NamedSchemaComponent::Ptr, QSourceLocation > m_componentLocationHash
static bool hasCircularUnionInheritance(const XsdSimpleType::Ptr &type, const SchemaType::Ptr &otherType, NamePool::Ptr &namePool)
virtual DerivationMethod derivationMethod() const =0
AnySimpleType::Ptr primitiveType() const
XsdAttribute::List attributes() const
Definition: qxsdschema.cpp:110
The element is defined globally as child of the schema object.
ValueConstraint::Ptr valueConstraint() const
QHashIterator< XsdFacet::Type, XsdFacet::Ptr > HashIterator
Definition: qxsdfacet_p.h:119
virtual bool isModelGroup() const
Definition: qxsdterm.cpp:53
bool hasDuplicatedAttributeUses(const XsdAttributeUse::List &list, XsdAttribute::Ptr &conflictingAttribute) const
AnySimpleType::List memberTypes() const
static const QTextHtmlElement elements[Html_NumElements]
XsdAttributeGroup::List attributeGroups() const
Definition: qxsdschema.cpp:202
static const AtomicType::Ptr xsAnyAtomicType
static bool isParticleEmptiable(const XsdParticle::Ptr &particle)
SchemaType::DerivationConstraints derivationConstraints() const
static QString formatAttribute(const QString &attribute)
Formats attribute name.
The attribute has a fixed value set.
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.
QHash< QXmlName, QSet< XsdFacet::Type > > m_allowedAtomicFacets
static const AtomicType::Ptr xsNOTATION
virtual bool isComplexType() const
QSourceLocation sourceLocationForType(const SchemaType::Ptr &type) const
The class that provides methods for checking a string against a type.
virtual SchemaType::Ptr wxsSuperType() const =0
The complex type has no further content.
QList< Key > keys() const
Returns a list containing all the keys in the hash, in an arbitrary order.
Definition: qhash.h:648
virtual QXmlName name(const NamePool::Ptr &namePool) const
virtual QXmlName name(const NamePool::Ptr &np) const =0
Returns the name of the type.
QHash< Key, T > & unite(const QHash< Key, T > &other)
Inserts all the items in the other hash into this hash.
Definition: qhash.h:556
bool hasMultipleIDAttributeUses(const XsdAttributeUse::List &list) const
Match the maximum length (Maximum Length Definition)
Definition: qxsdfacet_p.h:106
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)
Scope::Ptr scope() const
AnySimpleType::Ptr itemType() const