Qt 4.8
qxsdschemaparser.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 "qxsdschemaparser_p.h"
43 
44 #include "private/qxmlutils_p.h"
46 #include "qautoptr_p.h"
47 #include "qboolean_p.h"
48 #include "qcommonnamespaces_p.h"
49 #include "qderivedinteger_p.h"
50 #include "qderivedstring_p.h"
51 #include "qqnamevalue_p.h"
52 #include "qxmlquery_p.h"
53 #include "qxpathhelper_p.h"
55 #include "qxsdreference_p.h"
56 #include "qxsdschematoken_p.h"
57 
58 #include <QtCore/QFile>
59 #include <QtXmlPatterns/QXmlQuery>
60 
62 
103 using namespace QPatternist;
104 
105 namespace QPatternist
106 {
107 
114 {
115  public:
123  : m_parser(parser)
124  {
126  Q_UNUSED(tag)
129  }
130 
137  {
139  }
140 
141  private:
143 };
144 
150 {
151  public:
153  : m_parser(parser), m_machine(namePool)
154  {
155  Q_ASSERT(m_parser->m_stateMachines.contains(tag));
156 
157  m_machine = m_parser->m_stateMachines.value(tag);
158  m_machine.reset();
159  }
160 
162  {
163  if (token == XsdSchemaToken::NoKeyword) {
164  const QList<XsdSchemaToken::NodeName> tokens = m_machine.possibleTransitions();
165 
166  QStringList elementNames;
167  for (int i = 0; i < tokens.count(); ++i)
168  elementNames.append(formatElement(XsdSchemaToken::toString(tokens.at(i))));
169 
170  m_parser->error(QtXmlPatterns::tr("Can not process unknown element %1, expected elements are: %2.")
171  .arg(formatElement(m_parser->name().toString()))
172  .arg(elementNames.join(QLatin1String(", "))));
173  return;
174  }
175 
176  if (!m_machine.proceed(token)) {
177  const QList<XsdSchemaToken::NodeName> tokens = m_machine.possibleTransitions();
178 
179  QStringList elementNames;
180  for (int i = 0; i < tokens.count(); ++i)
181  elementNames.append(formatElement(XsdSchemaToken::toString(tokens.at(i))));
182 
183  m_parser->error(QtXmlPatterns::tr("Element %1 is not allowed in this scope, possible elements are: %2.")
185  .arg(elementNames.join(QLatin1String(", "))));
186  return;
187  }
188  }
189 
190  void finalize() const
191  {
192  if (!m_machine.inEndState()) {
193  const QList<XsdSchemaToken::NodeName> tokens = m_machine.possibleTransitions();
194 
195  QStringList elementNames;
196  for (int i = 0; i < tokens.count(); ++i)
197  elementNames.append(formatElement(XsdSchemaToken::toString(tokens.at(i))));
198 
199  m_parser->error(QtXmlPatterns::tr("Child element is missing in that scope, possible child elements are: %1.")
200  .arg(elementNames.join(QLatin1String(", "))));
201  }
202  }
203 
204  private:
207 };
208 
209 }
210 
216 {
217  XsdParticle::List refParticles;
218 
219  XsdParticle::List particles = group->particles();
220  for (int i = 0; i < particles.count(); ++i) {
221  if (particles.at(i)->term()->isReference()) {
222  const XsdReference::Ptr reference(particles.at(i)->term());
223  if (reference->type() == XsdReference::ModelGroup)
224  refParticles.append(particles.at(i));
225  }
226  if (particles.at(i)->term()->isModelGroup()) {
227  refParticles << collectGroupRef(XsdModelGroup::Ptr(particles.at(i)->term()));
228  }
229  }
230 
231  return refParticles;
232 }
233 
238 inline static bool isValidUri(const QString &string)
239 {
240  // an empty URI points to the current document as defined in RFC 2396 (4.2)
241  if (string.isEmpty())
242  return true;
243 
244  // explicit check as that is not checked by the code below
245  if (string.startsWith(QLatin1String("##")))
246  return false;
247 
248  const AnyURI::Ptr uri = AnyURI::fromLexical(string);
249  return (!(uri->hasError()));
250 }
251 
253  : MaintainingReader<XsdSchemaToken, XsdTagScope::Type>(parserContext->elementDescriptions(), QSet<XsdSchemaToken::NodeName>(), context, device)
254  , m_context(context.data())
255  , m_parserContext(parserContext.data())
256  , m_namePool(m_parserContext->namePool().data())
257  , m_namespaceSupport(*m_namePool)
258 {
262 
265 }
266 
268 {
269  m_includedSchemas += schemas;
270 }
271 
273 {
274  m_includedSchemas = schemas;
275 }
276 
278 {
279  m_importedSchemas += schemas;
280 }
281 
283 {
284  m_importedSchemas = schemas;
285 }
286 
288 {
289  m_redefinedSchemas += schemas;
290 }
291 
293 {
294  m_redefinedSchemas = schemas;
295 }
296 
297 void XsdSchemaParser::setTargetNamespace(const QString &targetNamespace)
298 {
299  m_targetNamespace = targetNamespace;
300 }
301 
303 {
304  m_targetNamespace = targetNamespace;
306 }
307 
309 {
310  m_documentURI = uri;
311 
312  // prevent to get included/imported/redefined twice
316 }
317 
319 {
320  return m_documentURI;
321 }
322 
324 {
325  return false;
326 }
327 
329 {
331 
332  while (!atEnd()) {
333  readNext();
334 
335  if (isStartElement()) {
338 
339  if (isSchemaTag(XsdSchemaToken::Schema, token, namespaceToken)) {
340  parseSchema(parserType);
341  } else {
342  error(QtXmlPatterns::tr("Document is not a XML schema."));
343  }
344  }
345  }
346 
349 
351  error(errorString());
352 
353  return true;
354 }
355 
357 {
359 }
360 
361 void XsdSchemaParser::attributeContentError(const char *attributeName, const char *elementName, const QString &value, const SchemaType::Ptr &type)
362 {
363  if (type) {
364  error(QtXmlPatterns::tr("%1 attribute of %2 element contains invalid content: {%3} is not a value of type %4.")
365  .arg(formatAttribute(attributeName))
366  .arg(formatElement(elementName))
367  .arg(formatData(value))
368  .arg(formatType(NamePool::Ptr(m_namePool), type)));
369  } else {
370  error(QtXmlPatterns::tr("%1 attribute of %2 element contains invalid content: {%3}.")
371  .arg(formatAttribute(attributeName))
372  .arg(formatElement(elementName))
373  .arg(formatData(value)));
374  }
375 }
376 
378 {
379  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Schema, this);
380 
382 
383  // parse attributes
384 
385  if (parserType == TopLevelParser) {
386  if (hasAttribute(QString::fromLatin1("targetNamespace"))) {
387  m_targetNamespace = readNamespaceAttribute(QString::fromLatin1("targetNamespace"), "schema");
388  }
389  } else if (parserType == IncludeParser) {
390  // m_targetNamespace is set to the target namespace of the including schema at this point
391 
392  if (hasAttribute(QString::fromLatin1("targetNamespace"))) {
393  const QString targetNamespace = readNamespaceAttribute(QString::fromLatin1("targetNamespace"), "schema");
394 
395  if (m_targetNamespace != targetNamespace) {
396  error(QtXmlPatterns::tr("Target namespace %1 of included schema is different from the target namespace %2 as defined by the including schema.")
397  .arg(formatURI(targetNamespace)).arg(formatURI(m_targetNamespace)));
398  return;
399  }
400  }
401  } else if (parserType == ImportParser) {
402  // m_targetNamespace is set to the target namespace from the namespace attribute of the <import> tag at this point
403 
404  QString targetNamespace;
405  if (hasAttribute(QString::fromLatin1("targetNamespace"))) {
406  targetNamespace = readNamespaceAttribute(QString::fromLatin1("targetNamespace"), "schema");
407  }
408 
409  if (m_targetNamespace != targetNamespace) {
410  error(QtXmlPatterns::tr("Target namespace %1 of imported schema is different from the target namespace %2 as defined by the importing schema.")
411  .arg(formatURI(targetNamespace)).arg(formatURI(m_targetNamespace)));
412  return;
413  }
414  } else if (parserType == RedefineParser) {
415  // m_targetNamespace is set to the target namespace of the redefining schema at this point
416 
417  if (hasAttribute(QString::fromLatin1("targetNamespace"))) {
418  const QString targetNamespace = readNamespaceAttribute(QString::fromLatin1("targetNamespace"), "schema");
419 
420  if (m_targetNamespace != targetNamespace) {
421  error(QtXmlPatterns::tr("Target namespace %1 of imported schema is different from the target namespace %2 as defined by the importing schema.")
422  .arg(formatURI(targetNamespace)).arg(formatURI(m_targetNamespace)));
423  return;
424  }
425  }
426  }
427 
428  if (hasAttribute(QString::fromLatin1("attributeFormDefault"))) {
429  const QString value = readAttribute(QString::fromLatin1("attributeFormDefault"));
430  if (value != QString::fromLatin1("qualified") && value != QString::fromLatin1("unqualified")) {
431  attributeContentError("attributeFormDefault", "schema", value);
432  return;
433  }
434 
435  m_attributeFormDefault = value;
436  } else {
438  }
439 
440  if (hasAttribute(QString::fromLatin1("elementFormDefault"))) {
441  const QString value = readAttribute(QString::fromLatin1("elementFormDefault"));
442  if (value != QString::fromLatin1("qualified") && value != QString::fromLatin1("unqualified")) {
443  attributeContentError("elementFormDefault", "schema", value);
444  return;
445  }
446 
447  m_elementFormDefault = value;
448  } else {
449  m_elementFormDefault = QString::fromLatin1("unqualified");
450  }
451 
452  if (hasAttribute(QString::fromLatin1("blockDefault"))) {
453  const QString blockDefault = readAttribute(QString::fromLatin1("blockDefault"));
454  const QStringList blockDefaultList = blockDefault.split(QLatin1Char(' '), QString::SkipEmptyParts);
455  for (int i = 0; i < blockDefaultList.count(); ++i) {
456  const QString value = blockDefaultList.at(i);
457  if (value != QString::fromLatin1("#all") &&
458  value != QString::fromLatin1("extension") &&
459  value != QString::fromLatin1("restriction") &&
460  value != QString::fromLatin1("substitution")) {
461  attributeContentError("blockDefault", "schema", value);
462  return;
463  }
464  }
465 
466  m_blockDefault = blockDefault;
467  }
468 
469  if (hasAttribute(QString::fromLatin1("finalDefault"))) {
470  const QString finalDefault = readAttribute(QString::fromLatin1("finalDefault"));
471  const QStringList finalDefaultList = finalDefault.split(QLatin1Char(' '), QString::SkipEmptyParts);
472  for (int i = 0; i < finalDefaultList.count(); ++i) {
473  const QString value = finalDefaultList.at(i);
474  if (value != QString::fromLatin1("#all") &&
475  value != QString::fromLatin1("extension") &&
476  value != QString::fromLatin1("restriction") &&
477  value != QString::fromLatin1("list") &&
478  value != QString::fromLatin1("union")) {
479  attributeContentError("finalDefault", "schema", value);
480  return;
481  }
482  }
483 
484  m_finalDefault = finalDefault;
485  }
486 
487  if (hasAttribute(QString::fromLatin1("xpathDefaultNamespace"))) {
488  const QString xpathDefaultNamespace = readAttribute(QString::fromLatin1("xpathDefaultNamespace"));
489  if (xpathDefaultNamespace != QString::fromLatin1("##defaultNamespace") &&
490  xpathDefaultNamespace != QString::fromLatin1("##targetNamespace") &&
491  xpathDefaultNamespace != QString::fromLatin1("##local")) {
492  if (!isValidUri(xpathDefaultNamespace)) {
493  attributeContentError("xpathDefaultNamespace", "schema", xpathDefaultNamespace);
494  return;
495  }
496  }
497  m_xpathDefaultNamespace = xpathDefaultNamespace;
498  } else {
500  }
501 
502  if (hasAttribute(QString::fromLatin1("defaultAttributes"))) {
503  const QString attrGroupName = readQNameAttribute(QString::fromLatin1("defaultAttributes"), "schema");
504  convertName(attrGroupName, NamespaceSupport::ElementName, m_defaultAttributes); // translate qualified name into QXmlName
505  }
506 
507  if (hasAttribute(QString::fromLatin1("version"))) {
508  const QString version = readAttribute(QString::fromLatin1("version"));
509  }
510 
513 
514  const QRegExp exp(QString::fromLatin1("[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*"));
515  if (!exp.exactMatch(value)) {
516  attributeContentError("xml:lang", "schema", value);
517  return;
518  }
519  }
520 
521  validateIdAttribute("schema");
522 
524 
525  while (!atEnd()) {
526  readNext();
527 
528  if (isEndElement())
529  break;
530 
531  if (isStartElement()) {
534 
535  tagValidator.validate(token);
536 
537  if (isSchemaTag(XsdSchemaToken::Include, token, namespaceToken)) {
538  parseInclude();
539  } else if (isSchemaTag(XsdSchemaToken::Import, token, namespaceToken)) {
540  parseImport();
541  } else if (isSchemaTag(XsdSchemaToken::Redefine, token, namespaceToken)) {
542  parseRedefine();
543  } else if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
544  const XsdAnnotation::Ptr annotation = parseAnnotation();
545  m_schema->addAnnotation(annotation);
546  } else if (isSchemaTag(XsdSchemaToken::DefaultOpenContent, token, namespaceToken)) {
548  } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
550  addType(type);
551  } else if (isSchemaTag(XsdSchemaToken::ComplexType, token, namespaceToken)) {
553  addType(type);
554  } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) {
555  const XsdModelGroup::Ptr group = parseNamedGroup();
556  addElementGroup(group);
557  } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) {
559  addAttributeGroup(attributeGroup);
560  } else if (isSchemaTag(XsdSchemaToken::Element, token, namespaceToken)) {
561  const XsdElement::Ptr element = parseGlobalElement();
562  addElement(element);
563  } else if (isSchemaTag(XsdSchemaToken::Attribute, token, namespaceToken)) {
564  const XsdAttribute::Ptr attribute = parseGlobalAttribute();
565  addAttribute(attribute);
566  } else if (isSchemaTag(XsdSchemaToken::Notation, token, namespaceToken)) {
567  const XsdNotation::Ptr notation = parseNotation();
568  addNotation(notation);
569  } else {
570  parseUnknown();
571  }
572  }
573  }
574 
575  tagValidator.finalize();
576 
578 }
579 
581 {
584 
586 
587  // parse attributes
588  const QString schemaLocation = readAttribute(QString::fromLatin1("schemaLocation"));
589 
590  QUrl url(schemaLocation);
591  if (url.isRelative()) {
593 
594  url = m_documentURI.resolved(url);
595  }
596 
597  if (m_includedSchemas.contains(url)) {
598  // we have included that file already, according to the schema spec we are
599  // allowed to silently skip it.
600  } else {
602 
605  if (reply) {
606  // parse the included schema by a different parser but with the same context
608  parser.setDocumentURI(url);
609  parser.setTargetNamespaceExtended(m_targetNamespace);
610  parser.setIncludedSchemas(m_includedSchemas);
611  parser.setImportedSchemas(m_importedSchemas);
612  parser.setRedefinedSchemas(m_redefinedSchemas);
613  if (!parser.parse(XsdSchemaParser::IncludeParser)) {
614  return;
615  } else {
616  // add indirectly loaded schemas to the list of already loaded ones
617  addIncludedSchemas(parser.m_includedSchemas);
618  addImportedSchemas(parser.m_importedSchemas);
619  addRedefinedSchemas(parser.m_redefinedSchemas);
620  }
621  }
622  }
623 
624  validateIdAttribute("include");
625 
627 
628  while (!atEnd()) {
629  readNext();
630 
631  if (isEndElement())
632  break;
633 
634  if (isStartElement()) {
637 
638  tagValidator.validate(token);
639 
640  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
641  const XsdAnnotation::Ptr annotation = parseAnnotation();
642  m_schema->addAnnotation(annotation);
643  } else {
644  parseUnknown();
645  }
646  }
647  }
648 
649  tagValidator.finalize();
650 }
651 
653 {
656 
658 
659  // parse attributes
660  QString importNamespace;
661  if (hasAttribute(QString::fromLatin1("namespace"))) {
662  importNamespace = readAttribute(QString::fromLatin1("namespace"));
663  if (importNamespace == m_targetNamespace) {
664  error(QtXmlPatterns::tr("%1 element is not allowed to have the same %2 attribute value as the target namespace %3.")
665  .arg(formatElement("import"))
666  .arg(formatAttribute("namespace"))
668  return;
669  }
670  } else {
671  if (m_targetNamespace.isEmpty()) {
672  error(QtXmlPatterns::tr("%1 element without %2 attribute is not allowed inside schema without target namespace.")
673  .arg(formatElement("import"))
674  .arg(formatAttribute("namespace")));
675  return;
676  }
677  }
678 
679  if (hasAttribute(QString::fromLatin1("schemaLocation"))) {
680  const QString schemaLocation = readAttribute(QString::fromLatin1("schemaLocation"));
681 
682  QUrl url(schemaLocation);
683  if (url.isRelative()) {
685 
686  url = m_documentURI.resolved(url);
687  }
688 
689  if (m_importedSchemas.contains(url)) {
690  // we have imported that file already, according to the schema spec we are
691  // allowed to silently skip it.
692  } else {
694 
695  // as it is possible that well known schemas (e.g. XSD for XML) are only referenced by
696  // namespace we should add it as well
697  m_importedSchemas.insert(importNamespace);
698 
701  if (reply) {
702  // parse the included schema by a different parser but with the same context
704  parser.setDocumentURI(url);
705  parser.setTargetNamespace(importNamespace);
706  parser.setIncludedSchemas(m_includedSchemas);
707  parser.setImportedSchemas(m_importedSchemas);
708  parser.setRedefinedSchemas(m_redefinedSchemas);
709  if (!parser.parse(XsdSchemaParser::ImportParser)) {
710  return;
711  } else {
712  // add indirectly loaded schemas to the list of already loaded ones
713  addIncludedSchemas(parser.m_includedSchemas);
714  addImportedSchemas(parser.m_importedSchemas);
715  addRedefinedSchemas(parser.m_redefinedSchemas);
716  }
717  }
718  }
719  } else {
720  // check whether it is a known namespace we have a builtin schema for
721  if (!importNamespace.isEmpty()) {
722  if (!m_importedSchemas.contains(importNamespace)) {
723  m_importedSchemas.insert(importNamespace);
724 
725  QFile file(QString::fromLatin1(":") + importNamespace);
726  if (file.open(QIODevice::ReadOnly)) {
728  parser.setDocumentURI(importNamespace);
729  parser.setTargetNamespace(importNamespace);
733  if (!parser.parse(XsdSchemaParser::ImportParser)) {
734  return;
735  } else {
736  // add indirectly loaded schemas to the list of already loaded ones
740  }
741  }
742  }
743  } else {
744  // we don't import anything... that is valid according to the schema
745  }
746  }
747 
748  validateIdAttribute("import");
749 
751 
752  while (!atEnd()) {
753  readNext();
754 
755  if (isEndElement())
756  break;
757 
758  if (isStartElement()) {
761 
762  tagValidator.validate(token);
763 
764  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
765  const XsdAnnotation::Ptr annotation = parseAnnotation();
766  m_schema->addAnnotation(annotation);
767  } else {
768  parseUnknown();
769  }
770  }
771  }
772 
773  tagValidator.finalize();
774 }
775 
777 {
780 
782 
783  // parse attributes
784  validateIdAttribute("redefine");
785 
786  const QString schemaLocation = readAttribute(QString::fromLatin1("schemaLocation"));
787 
789 
790  XsdSimpleType::List redefinedSimpleTypes;
791  XsdComplexType::List redefinedComplexTypes;
792  XsdModelGroup::List redefinedGroups;
793  XsdAttributeGroup::List redefinedAttributeGroups;
794 
795  while (!atEnd()) {
796  readNext();
797 
798  if (isEndElement())
799  break;
800 
801  if (isStartElement()) {
804 
805  tagValidator.validate(token);
806 
807  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
808  const XsdAnnotation::Ptr annotation = parseAnnotation();
809  m_schema->addAnnotation(annotation);
810  } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
812  redefinedSimpleTypes.append(type);
813 
814  const QXmlName baseTypeName = m_parserContext->resolver()->baseTypeNameOfType(type);
815  if (baseTypeName != type->name(NamePool::Ptr(m_namePool))) {
816  error(QString::fromLatin1("redefined simple type %1 must have itself as base type").arg(formatType(NamePool::Ptr(m_namePool), type)));
817  return;
818  }
819  } else if (isSchemaTag(XsdSchemaToken::ComplexType, token, namespaceToken)) {
821  redefinedComplexTypes.append(type);
822 
823  // @see http://www.w3.org/TR/xmlschema11-1/#src-redefine
824 
825  // 5
826  const QXmlName baseTypeName = m_parserContext->resolver()->baseTypeNameOfType(type);
827  if (baseTypeName != type->name(NamePool::Ptr(m_namePool))) {
828  error(QString::fromLatin1("redefined complex type %1 must have itself as base type").arg(formatType(NamePool::Ptr(m_namePool), type)));
829  return;
830  }
831  } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) {
832  const XsdModelGroup::Ptr group = parseNamedGroup();
833  redefinedGroups.append(group);
834  } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) {
836  redefinedAttributeGroups.append(group);
837 
838  } else {
839  parseUnknown();
840  }
841  }
842  }
843 
844  bool locationMustResolve = false;
845  if (!redefinedSimpleTypes.isEmpty() || !redefinedComplexTypes.isEmpty() ||
846  !redefinedGroups.isEmpty() || !redefinedAttributeGroups.isEmpty()) {
847  locationMustResolve = true;
848  }
849 
850  QUrl url(schemaLocation);
851  if (url.isRelative()) {
853 
854  url = m_documentURI.resolved(url);
855  }
856 
857  // we parse the schema given in the redefine tag into its own context
859 
860  if (m_redefinedSchemas.contains(url)) {
861  // we have redefined that file already, according to the schema spec we are
862  // allowed to silently skip it.
863  } else {
868  if (reply) {
869  // parse the included schema by a different parser but with the same context
870  XsdSchemaParser parser(XsdSchemaContext::Ptr(m_context), redefinedContext, reply);
871  parser.setDocumentURI(url);
876  if (!parser.parse(XsdSchemaParser::RedefineParser)) {
877  return;
878  } else {
879  // add indirectly loaded schemas to the list of already loaded ones
883  }
884 
885  delete reply;
886  }
887  }
888 
889  XsdSimpleType::List contextSimpleTypes = redefinedContext->schema()->simpleTypes();
890  XsdComplexType::List contextComplexTypes = redefinedContext->schema()->complexTypes();
891  XsdModelGroup::List contextGroups = redefinedContext->schema()->elementGroups();
892  XsdAttributeGroup::List contextAttributeGroups = redefinedContext->schema()->attributeGroups();
893 
894  // now we do the actual redefinition:
895 
896  // iterate over all redefined simple types
897  for (int i = 0; i < redefinedSimpleTypes.count(); ++i) {
898  XsdSimpleType::Ptr redefinedType = redefinedSimpleTypes.at(i);
899 
900  //TODONEXT: validation
901 
902  // search the definition they override in the context types
903  bool found = false;
904  for (int j = 0; j < contextSimpleTypes.count(); ++j) {
905  XsdSimpleType::Ptr contextType = contextSimpleTypes.at(j);
906 
907  if (redefinedType->name(NamePool::Ptr(m_namePool)) == contextType->name(NamePool::Ptr(m_namePool))) { // we found the right type
908  found = true;
909 
910  // 1) set name of context type to empty name
912 
913  // 2) set the context type as base type for the redefined type
914  redefinedType->setWxsSuperType(contextType);
915 
916  // 3) remove the base type resolving job from the resolver as
917  // we have set the base type here explicitly
919 
920  // 4) add the redefined type to the schema
921  addType(redefinedType);
922 
923  // 5) add the context type as anonymous type, so the resolver
924  // can resolve it further.
925  addAnonymousType(contextType);
926 
927  // 6) remove the context type from the list
928  contextSimpleTypes.removeAt(j);
929 
930  break;
931  }
932  }
933 
934  if (!found) {
935  error(QString::fromLatin1("no matching type found to redefine simple type %1").arg(formatType(NamePool::Ptr(m_namePool), redefinedType)));
936  return;
937  }
938  }
939 
940  // add all remaining context simple types to the schema
941  for (int i = 0; i < contextSimpleTypes.count(); ++i) {
942  addType(contextSimpleTypes.at(i));
943  }
944 
945  // iterate over all redefined complex types
946  for (int i = 0; i < redefinedComplexTypes.count(); ++i) {
947  XsdComplexType::Ptr redefinedType = redefinedComplexTypes.at(i);
948 
949  //TODONEXT: validation
950 
951  // search the definition they override in the context types
952  bool found = false;
953  for (int j = 0; j < contextComplexTypes.count(); ++j) {
954  XsdComplexType::Ptr contextType = contextComplexTypes.at(j);
955 
956  if (redefinedType->name(NamePool::Ptr(m_namePool)) == contextType->name(NamePool::Ptr(m_namePool))) { // we found the right type
957  found = true;
958 
959  // 1) set name of context type to empty name
961 
962  // 2) set the context type as base type for the redefined type
963  redefinedType->setWxsSuperType(contextType);
964 
965  // 3) remove the base type resolving job from the resolver as
966  // we have set the base type here explicitly
968 
969  // 4) add the redefined type to the schema
970  addType(redefinedType);
971 
972  // 5) add the context type as anonymous type, so the resolver
973  // can resolve its attribute uses etc.
974  addAnonymousType(contextType);
975 
976  // 6) remove the context type from the list
977  contextComplexTypes.removeAt(j);
978 
979  break;
980  }
981  }
982 
983  if (!found) {
984  error(QString::fromLatin1("no matching type found to redefine complex type %1").arg(formatType(NamePool::Ptr(m_namePool), redefinedType)));
985  return;
986  }
987  }
988 
989  // iterate over all redefined element groups
990  for (int i = 0; i < redefinedGroups.count(); ++i) {
991  const XsdModelGroup::Ptr group(redefinedGroups.at(i));
992 
993  // @see http://www.w3.org/TR/xmlschema11-1/#src-redefine
994 
995  // 6
996  const XsdParticle::List particles = collectGroupRef(group);
997  XsdParticle::Ptr referencedParticle;
998  int sameNameCounter = 0;
999  for (int i = 0; i < particles.count(); ++i) {
1000  const XsdReference::Ptr ref(particles.at(i)->term());
1001  if (ref->referenceName() == group->name(NamePool::Ptr(m_namePool))) {
1002  referencedParticle = particles.at(i);
1003 
1004  if (referencedParticle->minimumOccurs() != 1 || referencedParticle->maximumOccurs() != 1 || referencedParticle->maximumOccursUnbounded()) { // 6.1.2
1005  error(QString::fromLatin1("redefined group %1 can not contain reference to itself with minOccurs or maxOccurs != 1").arg(formatKeyword(group->displayName(NamePool::Ptr(m_namePool)))));
1006  return;
1007  }
1008  sameNameCounter++;
1009  }
1010  }
1011 
1012  // 6.1.1
1013  if (sameNameCounter > 1) {
1014  error(QString::fromLatin1("redefined group %1 can not contain multiple references to itself").arg(formatKeyword(group->displayName(NamePool::Ptr(m_namePool)))));
1015  return;
1016  }
1017 
1018  // search the group definition in the included schema (S2)
1019  XsdModelGroup::Ptr contextGroup;
1020  for (int j = 0; j < contextGroups.count(); ++j) {
1021  if (group->name(NamePool::Ptr(m_namePool)) == contextGroups.at(j)->name(NamePool::Ptr(m_namePool))) {
1022  contextGroup = contextGroups.at(j);
1023  break;
1024  }
1025  }
1026 
1027  if (!contextGroup) { // 6.2.1
1028  error(QString::fromLatin1("redefined group %1 has no occurrence in included schema").arg(formatKeyword(group->displayName(NamePool::Ptr(m_namePool)))));
1029  return;
1030  }
1031 
1032  if (sameNameCounter == 1) {
1033  // there was a self reference in the redefined group, so use the
1034  // group from the included schema
1035 
1036  // set a anonymous name to the group of the included schema
1038 
1039  // replace the self-reference with the group from the included schema
1040  referencedParticle->setTerm(contextGroup);
1041 
1042  addElementGroup(group);
1043 
1044  addElementGroup(contextGroup);
1045  contextGroups.removeAll(contextGroup);
1046  } else {
1047  // there was no self reference in the redefined group
1048 
1049  // just add the redefined group...
1050  addElementGroup(group);
1051 
1052  // we have to add them, otherwise it is not resolved and we can't validate it later
1054  addElementGroup(contextGroup);
1055 
1056  m_schemaResolver->addRedefinedGroups(group, contextGroup);
1057 
1058  // ...and forget about the group from the included schema
1059  contextGroups.removeAll(contextGroup);
1060  }
1061  }
1062 
1063  // iterate over all redefined attribute groups
1064  for (int i = 0; i < redefinedAttributeGroups.count(); ++i) {
1065  const XsdAttributeGroup::Ptr group(redefinedAttributeGroups.at(i));
1066 
1067  // @see http://www.w3.org/TR/xmlschema11-1/#src-redefine
1068 
1069  // 7
1070 
1071  // 7.1
1072  int sameNameCounter = 0;
1073  for (int j = 0; j < group->attributeUses().count(); ++j) {
1074  const XsdAttributeUse::Ptr attributeUse(group->attributeUses().at(j));
1075  if (attributeUse->isReference()) {
1076  const XsdAttributeReference::Ptr reference(attributeUse);
1077  if (reference->type() == XsdAttributeReference::AttributeGroup) {
1078  if (group->name(NamePool::Ptr(m_namePool)) == reference->referenceName())
1079  sameNameCounter++;
1080  }
1081  }
1082  }
1083  if (sameNameCounter > 1) {
1084  error(QString::fromLatin1("redefined attribute group %1 can not contain multiple references to itself").arg(formatKeyword(group->displayName(NamePool::Ptr(m_namePool)))));
1085  return;
1086  }
1087 
1088  // search the attribute group definition in the included schema (S2)
1089  XsdAttributeGroup::Ptr baseGroup;
1090  for (int j = 0; j < contextAttributeGroups.count(); ++j) {
1091  const XsdAttributeGroup::Ptr contextGroup(contextAttributeGroups.at(j));
1092  if (group->name(NamePool::Ptr(m_namePool)) == contextGroup->name(NamePool::Ptr(m_namePool))) {
1093  baseGroup = contextGroup;
1094  break;
1095  }
1096  }
1097 
1098  if (!baseGroup) { // 7.2.1
1099  error(QString::fromLatin1("redefined attribute group %1 has no occurrence in included schema").arg(formatKeyword(group->displayName(NamePool::Ptr(m_namePool)))));
1100  return;
1101  }
1102 
1103  if (sameNameCounter == 1) {
1104 
1105  // first set an anonymous name to the attribute group from the included
1106  // schema
1108 
1109  // iterate over the attribute uses of the redefined attribute group
1110  // and replace the self-reference with the attribute group from the
1111  // included schema
1112  for (int j = 0; j < group->attributeUses().count(); ++j) {
1113  const XsdAttributeUse::Ptr attributeUse(group->attributeUses().at(j));
1114  if (attributeUse->isReference()) {
1115  const XsdAttributeReference::Ptr reference(attributeUse);
1116  if (reference->type() == XsdAttributeReference::AttributeGroup) {
1117  if (group->name(NamePool::Ptr(m_namePool)) == reference->referenceName()) {
1118  reference->setReferenceName(baseGroup->name(NamePool::Ptr(m_namePool)));
1119  break;
1120  }
1121  }
1122  }
1123  }
1124 
1125  // add both groups to the target schema
1126  addAttributeGroup(baseGroup);
1127  addAttributeGroup(group);
1128 
1129  contextAttributeGroups.removeAll(baseGroup);
1130  }
1131 
1132  if (sameNameCounter == 0) { // 7.2
1133 
1134  // we have to add them, otherwise it is not resolved and we can't validate it later
1136  addAttributeGroup(baseGroup);
1137 
1138  m_schemaResolver->addRedefinedAttributeGroups(group, baseGroup);
1139 
1140  // just add the redefined attribute group to the target schema...
1141  addAttributeGroup(group);
1142 
1143  // ... and forget about the one from the included schema
1144  contextAttributeGroups.removeAll(baseGroup);
1145  }
1146  }
1147 
1148  // add all remaining context complex types to the schema
1149  for (int i = 0; i < contextComplexTypes.count(); ++i) {
1150  addType(contextComplexTypes.at(i));
1151  }
1152 
1153  // add all remaining context element groups to the schema
1154  for (int i = 0; i < contextGroups.count(); ++i) {
1155  addElementGroup(contextGroups.at(i));
1156  }
1157 
1158  // add all remaining context attribute groups to the schema
1159  for (int i = 0; i < contextAttributeGroups.count(); ++i) {
1160  addAttributeGroup(contextAttributeGroups.at(i));
1161  }
1162 
1163  // copy all elements, attributes and notations
1164  const XsdElement::List contextElements = redefinedContext->schema()->elements();
1165  for (int i = 0; i < contextElements.count(); ++i) {
1166  addElement(contextElements.at(i));
1167  }
1168 
1169  const XsdAttribute::List contextAttributes = redefinedContext->schema()->attributes();
1170  for (int i = 0; i < contextAttributes.count(); ++i) {
1171  addAttribute(contextAttributes.at(i));
1172  }
1173 
1174  const XsdNotation::List contextNotations = redefinedContext->schema()->notations();
1175  for (int i = 0; i < contextNotations.count(); ++i) {
1176  addNotation(contextNotations.at(i));
1177  }
1178 
1179  // push all data to resolve from the context resolver to our resolver
1180  redefinedContext->resolver()->copyDataTo(m_parserContext->resolver());
1181 
1182  tagValidator.finalize();
1183 }
1184 
1186 {
1187  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Annotation, this);
1188 
1190 
1191  // parse attributes
1192  validateIdAttribute("annotation");
1193 
1195 
1196  const XsdAnnotation::Ptr annotation(new XsdAnnotation());
1197 
1198  while (!atEnd()) {
1199  readNext();
1200 
1201  if (isEndElement())
1202  break;
1203 
1204  if (isStartElement()) {
1207 
1208  tagValidator.validate(token);
1209 
1210  if (isSchemaTag(XsdSchemaToken::Appinfo, token, namespaceToken)) {
1212  annotation->addApplicationInformation(info);
1213  } else if (isSchemaTag(XsdSchemaToken::Documentation, token, namespaceToken)) {
1214  const XsdDocumentation::Ptr documentation = parseDocumentation();
1215  annotation->addDocumentation(documentation);
1216  } else {
1217  parseUnknown();
1218  }
1219  }
1220  }
1221 
1222  tagValidator.finalize();
1223 
1224  return annotation;
1225 }
1226 
1228 {
1229  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Appinfo, this);
1230 
1232 
1234 
1235  // parse attributes
1236  if (hasAttribute(QString::fromLatin1("source"))) {
1237  const QString value = readAttribute(QString::fromLatin1("source"));
1238 
1239  if (!isValidUri(value)) {
1240  attributeContentError("source", "appinfo", value, BuiltinTypes::xsAnyURI);
1241  return info;
1242  }
1243 
1244  if (!value.isEmpty()) {
1245  const AnyURI::Ptr source = AnyURI::fromLexical(value);
1246  info->setSource(source);
1247  }
1248  }
1249 
1250  while (!atEnd()) { //EVAL: can be anything... what to do?
1251  readNext();
1252 
1253  if (isEndElement())
1254  break;
1255 
1256  if (isStartElement())
1258  }
1259 
1260  return info;
1261 }
1262 
1264 {
1265  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Documentation, this);
1266 
1268 
1269  const XsdDocumentation::Ptr documentation(new XsdDocumentation());
1270 
1271  // parse attributes
1272  if (hasAttribute(QString::fromLatin1("source"))) {
1273  const QString value = readAttribute(QString::fromLatin1("source"));
1274 
1275  if (!isValidUri(value)) {
1276  attributeContentError("source", "documentation", value, BuiltinTypes::xsAnyURI);
1277  return documentation;
1278  }
1279 
1280  if (!value.isEmpty()) {
1281  const AnyURI::Ptr source = AnyURI::fromLexical(value);
1282  documentation->setSource(source);
1283  }
1284  }
1285 
1288 
1289  const QRegExp exp(QString::fromLatin1("[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*"));
1290  if (!exp.exactMatch(value)) {
1291  attributeContentError("xml:lang", "documentation", value);
1292  return documentation;
1293  }
1294  }
1295 
1296  while (!atEnd()) { //EVAL: can by any... what to do?
1297  readNext();
1298 
1299  if (isEndElement())
1300  break;
1301 
1302  if (isStartElement())
1304  }
1305 
1306  return documentation;
1307 }
1308 
1310 {
1311  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::DefaultOpenContent, this);
1312 
1314 
1316 
1317  if (hasAttribute(QString::fromLatin1("appliesToEmpty"))) {
1318  const QString value = readAttribute(QString::fromLatin1("appliesToEmpty"));
1319  const Boolean::Ptr appliesToEmpty = Boolean::fromLexical(value);
1320  if (appliesToEmpty->hasError()) {
1321  attributeContentError("appliesToEmpty", "defaultOpenContent", value, BuiltinTypes::xsBoolean);
1322  return;
1323  }
1324 
1325  m_defaultOpenContentAppliesToEmpty = appliesToEmpty->as<Boolean>()->value();
1326  } else {
1328  }
1329 
1330  if (hasAttribute(QString::fromLatin1("mode"))) {
1331  const QString mode = readAttribute(QString::fromLatin1("mode"));
1332 
1333  if (mode == QString::fromLatin1("interleave")) {
1335  } else if (mode == QString::fromLatin1("suffix")) {
1337  } else {
1338  attributeContentError("mode", "defaultOpenContent", mode);
1339  return;
1340  }
1341  } else {
1343  }
1344 
1345  validateIdAttribute("defaultOpenContent");
1346 
1348 
1349  while (!atEnd()) {
1350  readNext();
1351 
1352  if (isEndElement())
1353  break;
1354 
1355  if (isStartElement()) {
1358 
1359  tagValidator.validate(token);
1360 
1361  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
1362  const XsdAnnotation::Ptr annotation = parseAnnotation();
1363  m_defaultOpenContent->addAnnotation(annotation);
1364  } else if (isSchemaTag(XsdSchemaToken::Any, token, namespaceToken)) {
1365  const XsdParticle::Ptr particle;
1366  const XsdWildcard::Ptr wildcard = parseAny(particle);
1367  m_defaultOpenContent->setWildcard(wildcard);
1368  } else {
1369  parseUnknown();
1370  }
1371  }
1372  }
1373 
1374  tagValidator.finalize();
1375 }
1376 
1378 {
1379  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::SimpleType, this);
1380 
1382 
1383  const XsdSimpleType::Ptr simpleType(new XsdSimpleType());
1384  simpleType->setCategory(XsdSimpleType::SimpleTypeAtomic); // just to make sure it's not invalid
1385 
1386  // parse attributes
1387  const SchemaType::DerivationConstraints allowedConstraints(SchemaType::ExtensionConstraint | SchemaType::RestrictionConstraint | SchemaType::ListConstraint | SchemaType::UnionConstraint);
1388  simpleType->setDerivationConstraints(readDerivationConstraintAttribute(allowedConstraints, "simpleType"));
1389 
1390  const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("simpleType"));
1391  simpleType->setName(objectName);
1392 
1393  validateIdAttribute("simpleType");
1394 
1396 
1397  while (!atEnd()) {
1398  readNext();
1399 
1400  if (isEndElement())
1401  break;
1402 
1403  if (isStartElement()) {
1406 
1407  tagValidator.validate(token);
1408 
1409  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
1410  const XsdAnnotation::Ptr annotation = parseAnnotation();
1411  simpleType->addAnnotation(annotation);
1412  } else if (isSchemaTag(XsdSchemaToken::Restriction, token, namespaceToken)) {
1413  parseSimpleRestriction(simpleType);
1414  } else if (isSchemaTag(XsdSchemaToken::List, token, namespaceToken)) {
1415  parseList(simpleType);
1416  } else if (isSchemaTag(XsdSchemaToken::Union, token, namespaceToken)) {
1417  parseUnion(simpleType);
1418  } else {
1419  parseUnknown();
1420  }
1421  }
1422  }
1423 
1424  tagValidator.finalize();
1425 
1426  return simpleType;
1427 }
1428 
1430 {
1431  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::SimpleType, this);
1432 
1434 
1435  const XsdSimpleType::Ptr simpleType(new XsdSimpleType());
1436  simpleType->setCategory(XsdSimpleType::SimpleTypeAtomic); // just to make sure it's not invalid
1438 
1439  validateIdAttribute("simpleType");
1440 
1442 
1443  while (!atEnd()) {
1444  readNext();
1445 
1446  if (isEndElement())
1447  break;
1448 
1449  if (isStartElement()) {
1452 
1453  tagValidator.validate(token);
1454 
1455  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
1456  const XsdAnnotation::Ptr annotation = parseAnnotation();
1457  simpleType->addAnnotation(annotation);
1458  } else if (isSchemaTag(XsdSchemaToken::Restriction, token, namespaceToken)) {
1459  parseSimpleRestriction(simpleType);
1460  } else if (isSchemaTag(XsdSchemaToken::List, token, namespaceToken)) {
1461  parseList(simpleType);
1462  } else if (isSchemaTag(XsdSchemaToken::Union, token, namespaceToken)) {
1463  parseUnion(simpleType);
1464  } else {
1465  parseUnknown();
1466  }
1467  }
1468  }
1469 
1470  tagValidator.finalize();
1471 
1472  return simpleType;
1473 }
1474 
1476 {
1477  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Restriction, this);
1478 
1480 
1482 
1483  // The base attribute and simpleType member are mutually exclusive,
1484  // so we keep track of that
1485  bool hasBaseAttribute = false;
1486  bool hasBaseTypeSpecified = false;
1487 
1488  QXmlName baseName;
1489  if (hasAttribute(QString::fromLatin1("base"))) {
1490  const QString base = readQNameAttribute(QString::fromLatin1("base"), "restriction");
1491  convertName(base, NamespaceSupport::ElementName, baseName); // translate qualified name into QXmlName
1492  m_schemaResolver->addSimpleRestrictionBase(ptr, baseName, currentSourceLocation()); // add to resolver
1493 
1494  hasBaseAttribute = true;
1495  hasBaseTypeSpecified = true;
1496  }
1497  validateIdAttribute("restriction");
1498 
1499  XsdFacet::Hash facets;
1500  QList<XsdFacet::Ptr> patternFacets;
1501  QList<XsdFacet::Ptr> enumerationFacets;
1502  QList<XsdFacet::Ptr> assertionFacets;
1503 
1505 
1506  while (!atEnd()) {
1507  readNext();
1508 
1509  if (isEndElement())
1510  break;
1511 
1512  if (isStartElement()) {
1515 
1516  tagValidator.validate(token);
1517 
1518  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
1519  const XsdAnnotation::Ptr annotation = parseAnnotation();
1520  ptr->addAnnotation(annotation);
1521  } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
1522  if (hasBaseAttribute) {
1523  error(QtXmlPatterns::tr("%1 element is not allowed inside %2 element if %3 attribute is present.")
1524  .arg(formatElement("simpleType"))
1525  .arg(formatElement("restriction"))
1526  .arg(formatAttribute("base")));
1527  return;
1528  }
1529 
1531  type->setContext(ptr);
1532  ptr->setWxsSuperType(type);
1533  ptr->setCategory(type->category());
1534  hasBaseTypeSpecified = true;
1535 
1536  // add it to list of anonymous types as well
1537  addAnonymousType(type);
1538  } else if (isSchemaTag(XsdSchemaToken::MinExclusive, token, namespaceToken)) {
1539  const XsdFacet::Ptr facet = parseMinExclusiveFacet();
1540  addFacet(facet, facets, ptr);
1541  } else if (isSchemaTag(XsdSchemaToken::MinInclusive, token, namespaceToken)) {
1542  const XsdFacet::Ptr facet = parseMinInclusiveFacet();
1543  addFacet(facet, facets, ptr);
1544  } else if (isSchemaTag(XsdSchemaToken::MaxExclusive, token, namespaceToken)) {
1545  const XsdFacet::Ptr facet = parseMaxExclusiveFacet();
1546  addFacet(facet, facets, ptr);
1547  } else if (isSchemaTag(XsdSchemaToken::MaxInclusive, token, namespaceToken)) {
1548  const XsdFacet::Ptr facet = parseMaxInclusiveFacet();
1549  addFacet(facet, facets, ptr);
1550  } else if (isSchemaTag(XsdSchemaToken::TotalDigits, token, namespaceToken)) {
1551  const XsdFacet::Ptr facet = parseTotalDigitsFacet();
1552  addFacet(facet, facets, ptr);
1553  } else if (isSchemaTag(XsdSchemaToken::FractionDigits, token, namespaceToken)) {
1554  const XsdFacet::Ptr facet = parseFractionDigitsFacet();
1555  addFacet(facet, facets, ptr);
1556  } else if (isSchemaTag(XsdSchemaToken::Length, token, namespaceToken)) {
1557  const XsdFacet::Ptr facet = parseLengthFacet();
1558  addFacet(facet, facets, ptr);
1559  } else if (isSchemaTag(XsdSchemaToken::MinLength, token, namespaceToken)) {
1560  const XsdFacet::Ptr facet = parseMinLengthFacet();
1561  addFacet(facet, facets, ptr);
1562  } else if (isSchemaTag(XsdSchemaToken::MaxLength, token, namespaceToken)) {
1563  const XsdFacet::Ptr facet = parseMaxLengthFacet();
1564  addFacet(facet, facets, ptr);
1565  } else if (isSchemaTag(XsdSchemaToken::Enumeration, token, namespaceToken)) {
1566  const XsdFacet::Ptr facet = parseEnumerationFacet();
1567  enumerationFacets.append(facet);
1568  } else if (isSchemaTag(XsdSchemaToken::WhiteSpace, token, namespaceToken)) {
1569  const XsdFacet::Ptr facet = parseWhiteSpaceFacet();
1570  addFacet(facet, facets, ptr);
1571  } else if (isSchemaTag(XsdSchemaToken::Pattern, token, namespaceToken)) {
1572  const XsdFacet::Ptr facet = parsePatternFacet();
1573  patternFacets.append(facet);
1574  } else if (isSchemaTag(XsdSchemaToken::Assertion, token, namespaceToken)) {
1575  const XsdFacet::Ptr facet = parseAssertionFacet();
1576  assertionFacets.append(facet);
1577  } else {
1578  parseUnknown();
1579  }
1580  }
1581  }
1582 
1583  if (!hasBaseTypeSpecified) {
1584  error(QtXmlPatterns::tr("%1 element has neither %2 attribute nor %3 child element.")
1585  .arg(formatElement("restriction"))
1586  .arg(formatAttribute("base"))
1587  .arg(formatElement("simpleType")));
1588  return;
1589  }
1590 
1591  // merge all pattern facets into one multi value facet
1592  if (!patternFacets.isEmpty()) {
1593  const XsdFacet::Ptr patternFacet(new XsdFacet());
1594  patternFacet->setType(XsdFacet::Pattern);
1595 
1596  AtomicValue::List multiValue;
1597  for (int i = 0; i < patternFacets.count(); ++i)
1598  multiValue << patternFacets.at(i)->multiValue();
1599 
1600  patternFacet->setMultiValue(multiValue);
1601  addFacet(patternFacet, facets, ptr);
1602  }
1603 
1604  // merge all enumeration facets into one multi value facet
1605  if (!enumerationFacets.isEmpty()) {
1606  const XsdFacet::Ptr enumerationFacet(new XsdFacet());
1607  enumerationFacet->setType(XsdFacet::Enumeration);
1608 
1609  AtomicValue::List multiValue;
1610  for (int i = 0; i < enumerationFacets.count(); ++i)
1611  multiValue << enumerationFacets.at(i)->multiValue();
1612 
1613  enumerationFacet->setMultiValue(multiValue);
1614  addFacet(enumerationFacet, facets, ptr);
1615  }
1616 
1617  // merge all assertion facets into one facet
1618  if (!assertionFacets.isEmpty()) {
1619  const XsdFacet::Ptr assertionFacet(new XsdFacet());
1620  assertionFacet->setType(XsdFacet::Assertion);
1621 
1622  XsdAssertion::List assertions;
1623  for (int i = 0; i < assertionFacets.count(); ++i)
1624  assertions << assertionFacets.at(i)->assertions();
1625 
1626  assertionFacet->setAssertions(assertions);
1627  addFacet(assertionFacet, facets, ptr);
1628  }
1629 
1630  ptr->setFacets(facets);
1631 
1632  tagValidator.finalize();
1633 }
1634 
1636 {
1637  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::List, this);
1638 
1640 
1644 
1645  // The itemType attribute and simpleType member are mutually exclusive,
1646  // so we keep track of that
1647  bool hasItemTypeAttribute = false;
1648  bool hasItemTypeSpecified = false;
1649 
1650  if (hasAttribute(QString::fromLatin1("itemType"))) {
1651  const QString itemType = readQNameAttribute(QString::fromLatin1("itemType"), "list");
1653  convertName(itemType, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName
1654  m_schemaResolver->addSimpleListType(ptr, typeName, currentSourceLocation()); // add to resolver
1655 
1656  hasItemTypeAttribute = true;
1657  hasItemTypeSpecified = true;
1658  }
1659 
1660  validateIdAttribute("list");
1661 
1663 
1664  while (!atEnd()) {
1665  readNext();
1666 
1667  if (isEndElement())
1668  break;
1669 
1670  if (isStartElement()) {
1673 
1674  tagValidator.validate(token);
1675 
1676  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
1677  const XsdAnnotation::Ptr annotation = parseAnnotation();
1678  ptr->addAnnotation(annotation);
1679  } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
1680  if (hasItemTypeAttribute) {
1681  error(QtXmlPatterns::tr("%1 element is not allowed inside %2 element if %3 attribute is present.")
1682  .arg(formatElement("simpleType"))
1683  .arg(formatElement("list"))
1684  .arg(formatAttribute("itemType")));
1685  return;
1686  }
1687 
1689  type->setContext(ptr);
1690  ptr->setItemType(type);
1691 
1692  hasItemTypeSpecified = true;
1693 
1694  // add it to list of anonymous types as well
1695  addAnonymousType(type);
1696  } else {
1697  parseUnknown();
1698  }
1699  }
1700  }
1701 
1702  if (!hasItemTypeSpecified) {
1703  error(QtXmlPatterns::tr("%1 element has neither %2 attribute nor %3 child element.")
1704  .arg(formatElement("list"))
1705  .arg(formatAttribute("itemType"))
1706  .arg(formatElement("simpleType")));
1707  return;
1708  }
1709 
1710  tagValidator.finalize();
1711 
1712  // add the default white space facet that every simple type with list derivation has
1713  const XsdFacet::Ptr defaultFacet(new XsdFacet());
1714  defaultFacet->setType(XsdFacet::WhiteSpace);
1715  defaultFacet->setFixed(true);
1717  XsdFacet::Hash facets;
1718  facets.insert(defaultFacet->type(), defaultFacet);
1719  ptr->setFacets(facets);
1720 }
1721 
1723 {
1724  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Union, this);
1725 
1727 
1731 
1732  // The memberTypes attribute is not allowed to be empty,
1733  // so we keep track of that
1734  bool hasMemberTypesSpecified = false;
1735 
1736  if (hasAttribute(QString::fromLatin1("memberTypes"))) {
1737  const QStringList memberTypes = readAttribute(QString::fromLatin1("memberTypes")).split(QLatin1Char(' '), QString::SkipEmptyParts);
1738  QList<QXmlName> typeNames;
1739 
1740  for (int i = 0; i < memberTypes.count(); ++i) {
1742  convertName(memberTypes.at(i), NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName
1743  typeNames.append(typeName);
1744  }
1745 
1746  if (!typeNames.isEmpty()) {
1747  m_schemaResolver->addSimpleUnionTypes(ptr, typeNames, currentSourceLocation()); // add to resolver
1748  hasMemberTypesSpecified = true;
1749  }
1750  }
1751 
1752  validateIdAttribute("union");
1753 
1754  AnySimpleType::List memberTypes;
1755 
1757 
1758  while (!atEnd()) {
1759  readNext();
1760 
1761  if (isEndElement())
1762  break;
1763 
1764  if (isStartElement()) {
1767 
1768  tagValidator.validate(token);
1769 
1770  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
1771  const XsdAnnotation::Ptr annotation = parseAnnotation();
1772  ptr->addAnnotation(annotation);
1773  } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
1775  type->setContext(ptr);
1776  memberTypes.append(type);
1777 
1778  // add it to list of anonymous types as well
1779  addAnonymousType(type);
1780  } else {
1781  parseUnknown();
1782  }
1783  }
1784  }
1785 
1786  if (!memberTypes.isEmpty()) {
1787  ptr->setMemberTypes(memberTypes);
1788  hasMemberTypesSpecified = true;
1789  }
1790 
1791  if (!hasMemberTypesSpecified) {
1792  error(QtXmlPatterns::tr("%1 element has neither %2 attribute nor %3 child element.")
1793  .arg(formatElement("union"))
1794  .arg(formatAttribute("memberTypes"))
1795  .arg(formatElement("simpleType")));
1796  return;
1797  }
1798 
1799  tagValidator.finalize();
1800 }
1801 
1803 {
1804  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::MinExclusive, this);
1805 
1807 
1808  const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
1809  facet->setType(XsdFacet::MinimumExclusive);
1810 
1811  // parse attributes
1812  if (hasAttribute(QString::fromLatin1("fixed"))) {
1813  const QString value = readAttribute(QString::fromLatin1("fixed"));
1814  const Boolean::Ptr fixed = Boolean::fromLexical(value);
1815  if (fixed->hasError()) {
1816  attributeContentError("fixed", "minExclusive", value, BuiltinTypes::xsBoolean);
1817  return facet;
1818  }
1819 
1820  facet->setFixed(fixed->as<Boolean>()->value());
1821  } else {
1822  facet->setFixed(false); // the default value
1823  }
1824 
1825  // as minExclusive can have a value of type anySimpleType, we just read
1826  // the string here and store it for later intepretation
1827  const QString value = readAttribute(QString::fromLatin1("value"));
1829  if (string->hasError()) {
1830  attributeContentError("value", "minExclusive", value, BuiltinTypes::xsAnySimpleType);
1831  return facet;
1832  } else {
1833  facet->setValue(string);
1834  }
1835 
1836  validateIdAttribute("minExclusive");
1837 
1839 
1840  while (!atEnd()) {
1841  readNext();
1842 
1843  if (isEndElement())
1844  break;
1845 
1846  if (isStartElement()) {
1849 
1850  tagValidator.validate(token);
1851 
1852  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
1853  const XsdAnnotation::Ptr annotation = parseAnnotation();
1854  facet->addAnnotation(annotation);
1855  } else {
1856  parseUnknown();
1857  }
1858  }
1859  }
1860 
1861  tagValidator.finalize();
1862 
1863  return facet;
1864 }
1865 
1867 {
1868  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::MinInclusive, this);
1869 
1871 
1872  const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
1873  facet->setType(XsdFacet::MinimumInclusive);
1874 
1875  // parse attributes
1876  if (hasAttribute(QString::fromLatin1("fixed"))) {
1877  const QString value = readAttribute(QString::fromLatin1("fixed"));
1878  const Boolean::Ptr fixed = Boolean::fromLexical(value);
1879  if (fixed->hasError()) {
1880  attributeContentError("fixed", "minInclusive", value, BuiltinTypes::xsBoolean);
1881  return facet;
1882  }
1883 
1884  facet->setFixed(fixed->as<Boolean>()->value());
1885  } else {
1886  facet->setFixed(false); // the default value
1887  }
1888 
1889  // as minInclusive can have a value of type anySimpleType, we just read
1890  // the string here and store it for later intepretation
1891  const QString value = readAttribute(QString::fromLatin1("value"));
1893  if (string->hasError()) {
1894  attributeContentError("value", "minInclusive", value, BuiltinTypes::xsAnySimpleType);
1895  return facet;
1896  } else {
1897  facet->setValue(string);
1898  }
1899 
1900  validateIdAttribute("minInclusive");
1901 
1903 
1904  while (!atEnd()) {
1905  readNext();
1906 
1907  if (isEndElement())
1908  break;
1909 
1910  if (isStartElement()) {
1913 
1914  tagValidator.validate(token);
1915 
1916  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
1917  const XsdAnnotation::Ptr annotation = parseAnnotation();
1918  facet->addAnnotation(annotation);
1919  } else {
1920  parseUnknown();
1921  }
1922  }
1923  }
1924 
1925  tagValidator.finalize();
1926 
1927  return facet;
1928 }
1929 
1931 {
1932  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::MaxExclusive, this);
1933 
1935 
1936  const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
1937  facet->setType(XsdFacet::MaximumExclusive);
1938 
1939  // parse attributes
1940  if (hasAttribute(QString::fromLatin1("fixed"))) {
1941  const QString value = readAttribute(QString::fromLatin1("fixed"));
1942  const Boolean::Ptr fixed = Boolean::fromLexical(value);
1943  if (fixed->hasError()) {
1944  attributeContentError("fixed", "maxExclusive", value, BuiltinTypes::xsBoolean);
1945  return facet;
1946  }
1947 
1948  facet->setFixed(fixed->as<Boolean>()->value());
1949  } else {
1950  facet->setFixed(false); // the default value
1951  }
1952 
1953  // as maxExclusive can have a value of type anySimpleType, we just read
1954  // the string here and store it for later intepretation
1955  const QString value = readAttribute(QString::fromLatin1("value"));
1957  if (string->hasError()) {
1958  attributeContentError("value", "maxExclusive", value, BuiltinTypes::xsAnySimpleType);
1959  return facet;
1960  } else {
1961  facet->setValue(string);
1962  }
1963 
1964  validateIdAttribute("maxExclusive");
1965 
1967 
1968  while (!atEnd()) {
1969  readNext();
1970 
1971  if (isEndElement())
1972  break;
1973 
1974  if (isStartElement()) {
1977 
1978  tagValidator.validate(token);
1979 
1980  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
1981  const XsdAnnotation::Ptr annotation = parseAnnotation();
1982  facet->addAnnotation(annotation);
1983  } else {
1984  parseUnknown();
1985  }
1986  }
1987  }
1988 
1989  tagValidator.finalize();
1990 
1991  return facet;
1992 }
1993 
1995 {
1996  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::MaxInclusive, this);
1997 
1999 
2000  const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
2001  facet->setType(XsdFacet::MaximumInclusive);
2002 
2003  // parse attributes
2004  if (hasAttribute(QString::fromLatin1("fixed"))) {
2005  const QString value = readAttribute(QString::fromLatin1("fixed"));
2006  const Boolean::Ptr fixed = Boolean::fromLexical(value);
2007  if (fixed->hasError()) {
2008  attributeContentError("fixed", "maxInclusive", value, BuiltinTypes::xsBoolean);
2009  return facet;
2010  }
2011 
2012  facet->setFixed(fixed->as<Boolean>()->value());
2013  } else {
2014  facet->setFixed(false); // the default value
2015  }
2016 
2017  // as maxInclusive can have a value of type anySimpleType, we just read
2018  // the string here and store it for later intepretation
2019  const QString value = readAttribute(QString::fromLatin1("value"));
2021  if (string->hasError()) {
2022  attributeContentError("value", "maxInclusive", value, BuiltinTypes::xsAnySimpleType);
2023  return facet;
2024  } else {
2025  facet->setValue(string);
2026  }
2027 
2028  validateIdAttribute("maxInclusive");
2029 
2031 
2032  while (!atEnd()) {
2033  readNext();
2034 
2035  if (isEndElement())
2036  break;
2037 
2038  if (isStartElement()) {
2041 
2042  tagValidator.validate(token);
2043 
2044  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
2045  const XsdAnnotation::Ptr annotation = parseAnnotation();
2046  facet->addAnnotation(annotation);
2047  } else {
2048  parseUnknown();
2049  }
2050  }
2051  }
2052 
2053  tagValidator.finalize();
2054 
2055  return facet;
2056 }
2057 
2059 {
2060  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::TotalDigits, this);
2061 
2063 
2064  const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
2065  facet->setType(XsdFacet::TotalDigits);
2066 
2067  // parse attributes
2068  if (hasAttribute(QString::fromLatin1("fixed"))) {
2069  const QString value = readAttribute(QString::fromLatin1("fixed"));
2070  const Boolean::Ptr fixed = Boolean::fromLexical(value);
2071  if (fixed->hasError()) {
2072  attributeContentError("fixed", "totalDigits", value, BuiltinTypes::xsBoolean);
2073  return facet;
2074  }
2075 
2076  facet->setFixed(fixed->as<Boolean>()->value());
2077  } else {
2078  facet->setFixed(false); // the default value
2079  }
2080 
2081  const QString value = readAttribute(QString::fromLatin1("value"));
2083  if (integer->hasError()) {
2084  attributeContentError("value", "totalDigits", value, BuiltinTypes::xsPositiveInteger);
2085  return facet;
2086  } else {
2087  facet->setValue(integer);
2088  }
2089 
2090  validateIdAttribute("totalDigits");
2091 
2093 
2094  while (!atEnd()) {
2095  readNext();
2096 
2097  if (isEndElement())
2098  break;
2099 
2100  if (isStartElement()) {
2103 
2104  tagValidator.validate(token);
2105 
2106  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
2107  const XsdAnnotation::Ptr annotation = parseAnnotation();
2108  facet->addAnnotation(annotation);
2109  } else {
2110  parseUnknown();
2111  }
2112  }
2113  }
2114 
2115  tagValidator.finalize();
2116 
2117  return facet;
2118 }
2119 
2121 {
2122  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::FractionDigits, this);
2123 
2125 
2126  const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
2127  facet->setType(XsdFacet::FractionDigits);
2128 
2129  // parse attributes
2130  if (hasAttribute(QString::fromLatin1("fixed"))) {
2131  const QString value = readAttribute(QString::fromLatin1("fixed"));
2132  const Boolean::Ptr fixed = Boolean::fromLexical(value);
2133  if (fixed->hasError()) {
2134  attributeContentError("fixed", "fractionDigits", value, BuiltinTypes::xsBoolean);
2135  return facet;
2136  }
2137 
2138  facet->setFixed(fixed->as<Boolean>()->value());
2139  } else {
2140  facet->setFixed(false); // the default value
2141  }
2142 
2143  const QString value = readAttribute(QString::fromLatin1("value"));
2145  if (integer->hasError()) {
2146  attributeContentError("value", "fractionDigits", value, BuiltinTypes::xsNonNegativeInteger);
2147  return facet;
2148  } else {
2149  facet->setValue(integer);
2150  }
2151 
2152  validateIdAttribute("fractionDigits");
2153 
2155 
2156  while (!atEnd()) {
2157  readNext();
2158 
2159  if (isEndElement())
2160  break;
2161 
2162  if (isStartElement()) {
2165 
2166  tagValidator.validate(token);
2167 
2168  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
2169  const XsdAnnotation::Ptr annotation = parseAnnotation();
2170  facet->addAnnotation(annotation);
2171  } else {
2172  parseUnknown();
2173  }
2174  }
2175  }
2176 
2177  tagValidator.finalize();
2178 
2179  return facet;
2180 }
2181 
2183 {
2184  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Length, this);
2185 
2187 
2188  const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
2189  facet->setType(XsdFacet::Length);
2190 
2191  // parse attributes
2192  if (hasAttribute(QString::fromLatin1("fixed"))) {
2193  const QString value = readAttribute(QString::fromLatin1("fixed"));
2194  const Boolean::Ptr fixed = Boolean::fromLexical(value);
2195  if (fixed->hasError()) {
2196  attributeContentError("fixed", "length", value, BuiltinTypes::xsBoolean);
2197  return facet;
2198  }
2199 
2200  facet->setFixed(fixed->as<Boolean>()->value());
2201  } else {
2202  facet->setFixed(false); // the default value
2203  }
2204 
2205  const QString value = readAttribute(QString::fromLatin1("value"));
2207  if (integer->hasError()) {
2208  attributeContentError("value", "length", value, BuiltinTypes::xsNonNegativeInteger);
2209  return facet;
2210  } else {
2211  facet->setValue(integer);
2212  }
2213 
2214  validateIdAttribute("length");
2215 
2217 
2218  while (!atEnd()) {
2219  readNext();
2220 
2221  if (isEndElement())
2222  break;
2223 
2224  if (isStartElement()) {
2227 
2228  tagValidator.validate(token);
2229 
2230  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
2231  const XsdAnnotation::Ptr annotation = parseAnnotation();
2232  facet->addAnnotation(annotation);
2233  } else {
2234  parseUnknown();
2235  }
2236  }
2237  }
2238 
2239  tagValidator.finalize();
2240 
2241  return facet;
2242 }
2243 
2245 {
2246  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::MinLength, this);
2247 
2249 
2250  const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
2251  facet->setType(XsdFacet::MinimumLength);
2252 
2253  // parse attributes
2254  if (hasAttribute(QString::fromLatin1("fixed"))) {
2255  const QString value = readAttribute(QString::fromLatin1("fixed"));
2256  const Boolean::Ptr fixed = Boolean::fromLexical(value);
2257  if (fixed->hasError()) {
2258  attributeContentError("fixed", "minLength", value, BuiltinTypes::xsBoolean);
2259  return facet;
2260  }
2261 
2262  facet->setFixed(fixed->as<Boolean>()->value());
2263  } else {
2264  facet->setFixed(false); // the default value
2265  }
2266 
2267  const QString value = readAttribute(QString::fromLatin1("value"));
2269  if (integer->hasError()) {
2270  attributeContentError("value", "minLength", value, BuiltinTypes::xsNonNegativeInteger);
2271  return facet;
2272  } else {
2273  facet->setValue(integer);
2274  }
2275 
2276  validateIdAttribute("minLength");
2277 
2279 
2280  while (!atEnd()) {
2281  readNext();
2282 
2283  if (isEndElement())
2284  break;
2285 
2286  if (isStartElement()) {
2289 
2290  tagValidator.validate(token);
2291 
2292  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
2293  const XsdAnnotation::Ptr annotation = parseAnnotation();
2294  facet->addAnnotation(annotation);
2295  } else {
2296  parseUnknown();
2297  }
2298  }
2299  }
2300 
2301  tagValidator.finalize();
2302 
2303  return facet;
2304 }
2305 
2307 {
2308  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::MaxLength, this);
2309 
2311 
2312  const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
2313  facet->setType(XsdFacet::MaximumLength);
2314 
2315  // parse attributes
2316  if (hasAttribute(QString::fromLatin1("fixed"))) {
2317  const QString value = readAttribute(QString::fromLatin1("fixed"));
2318  const Boolean::Ptr fixed = Boolean::fromLexical(value);
2319  if (fixed->hasError()) {
2320  attributeContentError("fixed", "maxLength", value, BuiltinTypes::xsBoolean);
2321  return facet;
2322  }
2323 
2324  facet->setFixed(fixed->as<Boolean>()->value());
2325  } else {
2326  facet->setFixed(false); // the default value
2327  }
2328 
2329  const QString value = readAttribute(QString::fromLatin1("value"));
2331  if (integer->hasError()) {
2332  attributeContentError("value", "maxLength", value, BuiltinTypes::xsNonNegativeInteger);
2333  return facet;
2334  } else {
2335  facet->setValue(integer);
2336  }
2337 
2338  validateIdAttribute("maxLength");
2339 
2341 
2342  while (!atEnd()) {
2343  readNext();
2344 
2345  if (isEndElement())
2346  break;
2347 
2348  if (isStartElement()) {
2351 
2352  tagValidator.validate(token);
2353 
2354  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
2355  const XsdAnnotation::Ptr annotation = parseAnnotation();
2356  facet->addAnnotation(annotation);
2357  } else {
2358  parseUnknown();
2359  }
2360  }
2361  }
2362 
2363  tagValidator.finalize();
2364 
2365  return facet;
2366 }
2367 
2369 {
2370  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Enumeration, this);
2371 
2373 
2374  const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
2375  facet->setType(XsdFacet::Enumeration);
2376 
2377  // parse attributes
2378  facet->setFixed(false); // not defined in schema, but can't hurt
2379 
2380  const QString value = readAttribute(QString::fromLatin1("value"));
2381 
2382  // as enumeration can have a value of type anySimpleType, we just read
2383  // the string here and store it for later intepretation
2385  if (string->hasError()) {
2386  attributeContentError("value", "enumeration", value);
2387  return facet;
2388  } else {
2389  AtomicValue::List multiValue;
2390  multiValue << string;
2391  facet->setMultiValue(multiValue);
2392  }
2394 
2395  validateIdAttribute("enumeration");
2396 
2398 
2399  while (!atEnd()) {
2400  readNext();
2401 
2402  if (isEndElement())
2403  break;
2404 
2405  if (isStartElement()) {
2408 
2409  tagValidator.validate(token);
2410 
2411  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
2412  const XsdAnnotation::Ptr annotation = parseAnnotation();
2413  facet->addAnnotation(annotation);
2414  } else {
2415  parseUnknown();
2416  }
2417  }
2418  }
2419 
2420  tagValidator.finalize();
2421 
2422  return facet;
2423 }
2424 
2426 {
2427  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::WhiteSpace, this);
2428 
2430 
2431  const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
2432  facet->setType(XsdFacet::WhiteSpace);
2433 
2434  // parse attributes
2435  if (hasAttribute(QString::fromLatin1("fixed"))) {
2436  const QString value = readAttribute(QString::fromLatin1("fixed"));
2437  const Boolean::Ptr fixed = Boolean::fromLexical(value);
2438  if (fixed->hasError()) {
2439  attributeContentError("fixed", "whiteSpace", value, BuiltinTypes::xsBoolean);
2440  return facet;
2441  }
2442 
2443  facet->setFixed(fixed->as<Boolean>()->value());
2444  } else {
2445  facet->setFixed(false); // the default value
2446  }
2447 
2448  const QString value = readAttribute(QString::fromLatin1("value"));
2452  attributeContentError("value", "whiteSpace", value);
2453  return facet;
2454  } else {
2456  if (string->hasError()) {
2457  attributeContentError("value", "whiteSpace", value);
2458  return facet;
2459  } else {
2460  facet->setValue(string);
2461  }
2462  }
2463 
2464  validateIdAttribute("whiteSpace");
2465 
2467 
2468  while (!atEnd()) {
2469  readNext();
2470 
2471  if (isEndElement())
2472  break;
2473 
2474  if (isStartElement()) {
2477 
2478  tagValidator.validate(token);
2479 
2480  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
2481  const XsdAnnotation::Ptr annotation = parseAnnotation();
2482  facet->addAnnotation(annotation);
2483  } else {
2484  parseUnknown();
2485  }
2486  }
2487  }
2488 
2489  tagValidator.finalize();
2490 
2491  return facet;
2492 }
2493 
2495 {
2496  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Pattern, this);
2497 
2499 
2500  const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
2501  facet->setType(XsdFacet::Pattern);
2502 
2503  // parse attributes
2504 
2505  // as pattern can have a value of type anySimpleType, we just read
2506  // the string here and store it for later intepretation
2507  const QString value = readAttribute(QString::fromLatin1("value"));
2509  if (string->hasError()) {
2510  attributeContentError("value", "pattern", value);
2511  return facet;
2512  } else {
2513  AtomicValue::List multiValue;
2514  multiValue << string;
2515  facet->setMultiValue(multiValue);
2516  }
2517 
2518  validateIdAttribute("pattern");
2519 
2521 
2522  while (!atEnd()) {
2523  readNext();
2524 
2525  if (isEndElement())
2526  break;
2527 
2528  if (isStartElement()) {
2531 
2532  tagValidator.validate(token);
2533 
2534  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
2535  const XsdAnnotation::Ptr annotation = parseAnnotation();
2536  facet->addAnnotation(annotation);
2537  } else {
2538  parseUnknown();
2539  }
2540  }
2541  }
2542 
2543  tagValidator.finalize();
2544 
2545  return facet;
2546 }
2547 
2549 {
2550  // this is just a wrapper function around the parseAssertion() method
2551 
2553 
2554  const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
2555  facet->setType(XsdFacet::Assertion);
2556  facet->setAssertions(XsdAssertion::List() << assertion);
2557 
2558  return facet;
2559 }
2560 
2562 {
2563  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::ComplexType, this);
2564 
2566 
2567  bool hasTypeSpecified = false;
2568  bool hasComplexContent = false;
2569 
2570  const XsdComplexType::Ptr complexType(new XsdComplexType());
2571 
2572  // parse attributes
2573  if (hasAttribute(QString::fromLatin1("abstract"))) {
2574  const QString abstract = readAttribute(QString::fromLatin1("abstract"));
2575 
2576  const Boolean::Ptr value = Boolean::fromLexical(abstract);
2577  if (value->hasError()) {
2578  attributeContentError("abstract", "complexType", abstract, BuiltinTypes::xsBoolean);
2579  return complexType;
2580  }
2581 
2582  complexType->setIsAbstract(value->as<Boolean>()->value());
2583  } else {
2584  complexType->setIsAbstract(false); // default value
2585  }
2586 
2589 
2590  const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("complexType"));
2591  complexType->setName(objectName);
2592 
2593  bool effectiveMixed = false;
2594  if (hasAttribute(QString::fromLatin1("mixed"))) {
2595  const QString mixed = readAttribute(QString::fromLatin1("mixed"));
2596 
2597  const Boolean::Ptr value = Boolean::fromLexical(mixed);
2598  if (value->hasError()) {
2599  attributeContentError("mixed", "complexType", mixed, BuiltinTypes::xsBoolean);
2600  return complexType;
2601  }
2602 
2603  effectiveMixed = value->as<Boolean>()->value();
2604  }
2605 
2606  validateIdAttribute("complexType");
2607 
2609 
2610  while (!atEnd()) {
2611  readNext();
2612 
2613  if (isEndElement())
2614  break;
2615 
2616  if (isStartElement()) {
2619 
2620  tagValidator.validate(token);
2621 
2622  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
2623  const XsdAnnotation::Ptr annotation = parseAnnotation();
2624  complexType->addAnnotation(annotation);
2625  } else if (isSchemaTag(XsdSchemaToken::SimpleContent, token, namespaceToken)) {
2626  if (effectiveMixed) {
2627  error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
2628  .arg(formatElement("complexType"))
2629  .arg(formatElement("simpleContent"))
2630  .arg(formatAttribute("mixed")));
2631  return complexType;
2632  }
2633 
2634  parseSimpleContent(complexType);
2635  hasTypeSpecified = true;
2636  } else if (isSchemaTag(XsdSchemaToken::ComplexContent, token, namespaceToken)) {
2637  bool mixed;
2638  parseComplexContent(complexType, &mixed);
2639  hasTypeSpecified = true;
2640 
2641  effectiveMixed = (effectiveMixed || mixed);
2642  hasComplexContent = true;
2643  } else if (isSchemaTag(XsdSchemaToken::OpenContent, token, namespaceToken)) {
2644  const XsdComplexType::OpenContent::Ptr openContent = parseOpenContent();
2645  complexType->contentType()->setOpenContent(openContent);
2646  hasComplexContent = true;
2647  } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) {
2648  const XsdParticle::Ptr particle(new XsdParticle());
2649  const XsdTerm::Ptr term = parseReferredGroup(particle);
2650  particle->setTerm(term);
2651  complexType->contentType()->setParticle(particle);
2652 
2654  complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
2656  hasComplexContent = true;
2657  } else if (isSchemaTag(XsdSchemaToken::All, token, namespaceToken)) {
2658  const XsdParticle::Ptr particle(new XsdParticle());
2659  const XsdTerm::Ptr term = parseLocalAll(particle, complexType);
2660  particle->setTerm(term);
2661  complexType->contentType()->setParticle(particle);
2662 
2664  complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
2666  hasComplexContent = true;
2667  } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) {
2668  const XsdParticle::Ptr particle(new XsdParticle());
2669  const XsdTerm::Ptr term = parseLocalChoice(particle, complexType);
2670  particle->setTerm(term);
2671  complexType->contentType()->setParticle(particle);
2672 
2674  complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
2676  hasComplexContent = true;
2677  } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) {
2678  const XsdParticle::Ptr particle(new XsdParticle());
2679  const XsdTerm::Ptr term = parseLocalSequence(particle, complexType);
2680  particle->setTerm(term);
2681  complexType->contentType()->setParticle(particle);
2682 
2684  complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
2686  hasComplexContent = true;
2687  } else if (isSchemaTag(XsdSchemaToken::Attribute, token, namespaceToken)) {
2688  const XsdAttributeUse::Ptr attributeUse = parseLocalAttribute(complexType);
2689  complexType->addAttributeUse(attributeUse);
2690 
2692  complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
2694  hasComplexContent = true;
2695  } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) {
2696  const XsdAttributeUse::Ptr attributeUse = parseReferredAttributeGroup();
2697  complexType->addAttributeUse(attributeUse);
2698 
2700  complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
2702  hasComplexContent = true;
2703  } else if (isSchemaTag(XsdSchemaToken::AnyAttribute, token, namespaceToken)) {
2704  const XsdWildcard::Ptr wildcard = parseAnyAttribute();
2705  complexType->setAttributeWildcard(wildcard);
2706 
2708  complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
2710  hasComplexContent = true;
2711  } else if (isSchemaTag(XsdSchemaToken::Assert, token, namespaceToken)) {
2713  complexType->addAssertion(assertion);
2714  } else {
2715  parseUnknown();
2716  }
2717  }
2718  }
2719 
2720  tagValidator.finalize();
2721 
2722  if (!hasTypeSpecified) {
2725  hasComplexContent = true;
2726  }
2727 
2728  if (hasComplexContent == true) {
2729  resolveComplexContentType(complexType, effectiveMixed);
2730  }
2731 
2732  return complexType;
2733 }
2734 
2736 {
2737  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::ComplexType, this);
2738 
2740 
2741  bool hasTypeSpecified = false;
2742  bool hasComplexContent = true;
2743 
2744  const XsdComplexType::Ptr complexType(new XsdComplexType());
2746 
2747  // parse attributes
2748  bool effectiveMixed = false;
2749  if (hasAttribute(QString::fromLatin1("mixed"))) {
2750  const QString mixed = readAttribute(QString::fromLatin1("mixed"));
2751 
2752  const Boolean::Ptr value = Boolean::fromLexical(mixed);
2753  if (value->hasError()) {
2754  attributeContentError("mixed", "complexType", mixed, BuiltinTypes::xsBoolean);
2755  return complexType;
2756  }
2757 
2758  effectiveMixed = value->as<Boolean>()->value();
2759  }
2760 
2761  validateIdAttribute("complexType");
2762 
2764 
2765  while (!atEnd()) {
2766  readNext();
2767 
2768  if (isEndElement())
2769  break;
2770 
2771  if (isStartElement()) {
2774 
2775  tagValidator.validate(token);
2776 
2777  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
2778  const XsdAnnotation::Ptr annotation = parseAnnotation();
2779  complexType->addAnnotation(annotation);
2780  } else if (isSchemaTag(XsdSchemaToken::SimpleContent, token, namespaceToken)) {
2781  parseSimpleContent(complexType);
2782  hasTypeSpecified = true;
2783  } else if (isSchemaTag(XsdSchemaToken::ComplexContent, token, namespaceToken)) {
2784  bool mixed;
2785  parseComplexContent(complexType, &mixed);
2786  hasTypeSpecified = true;
2787 
2788  effectiveMixed = (effectiveMixed || mixed);
2789  hasComplexContent = true;
2790  } else if (isSchemaTag(XsdSchemaToken::OpenContent, token, namespaceToken)) {
2791  const XsdComplexType::OpenContent::Ptr openContent = parseOpenContent();
2792  complexType->contentType()->setOpenContent(openContent);
2793  hasComplexContent = true;
2794  } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) {
2795  const XsdParticle::Ptr particle(new XsdParticle());
2796  const XsdTerm::Ptr term = parseReferredGroup(particle);
2797  particle->setTerm(term);
2798  complexType->contentType()->setParticle(particle);
2799 
2801  complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
2803  hasComplexContent = true;
2804  } else if (isSchemaTag(XsdSchemaToken::All, token, namespaceToken)) {
2805  const XsdParticle::Ptr particle(new XsdParticle());
2806  const XsdTerm::Ptr term = parseLocalAll(particle, complexType);
2807  particle->setTerm(term);
2808  complexType->contentType()->setParticle(particle);
2809 
2811  complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
2813  hasComplexContent = true;
2814  } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) {
2815  const XsdParticle::Ptr particle(new XsdParticle());
2816  const XsdTerm::Ptr term = parseLocalChoice(particle, complexType);
2817  particle->setTerm(term);
2818  complexType->contentType()->setParticle(particle);
2819 
2821  complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
2823  hasComplexContent = true;
2824  } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) {
2825  const XsdParticle::Ptr particle(new XsdParticle());
2826  const XsdTerm::Ptr term = parseLocalSequence(particle, complexType);
2827  particle->setTerm(term);
2828  complexType->contentType()->setParticle(particle);
2829 
2831  complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
2833  hasComplexContent = true;
2834  } else if (isSchemaTag(XsdSchemaToken::Attribute, token, namespaceToken)) {
2835  const XsdAttributeUse::Ptr attributeUse = parseLocalAttribute(complexType);
2836  complexType->addAttributeUse(attributeUse);
2837 
2839  complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
2841  hasComplexContent = true;
2842  } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) {
2843  const XsdAttributeUse::Ptr attributeUse = parseReferredAttributeGroup();
2844  complexType->addAttributeUse(attributeUse);
2845 
2847  complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
2849  hasComplexContent = true;
2850  } else if (isSchemaTag(XsdSchemaToken::AnyAttribute, token, namespaceToken)) {
2851  const XsdWildcard::Ptr wildcard = parseAnyAttribute();
2852  complexType->setAttributeWildcard(wildcard);
2853 
2855  complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
2857  hasComplexContent = true;
2858  } else if (isSchemaTag(XsdSchemaToken::Assert, token, namespaceToken)) {
2860  complexType->addAssertion(assertion);
2861  } else {
2862  parseUnknown();
2863  }
2864  }
2865  }
2866 
2867  tagValidator.finalize();
2868 
2869  if (!hasTypeSpecified) {
2872  hasComplexContent = true;
2873  }
2874 
2875  if (hasComplexContent == true) {
2876  resolveComplexContentType(complexType, effectiveMixed);
2877  }
2878 
2879  return complexType;
2880 }
2881 
2882 void XsdSchemaParser::resolveComplexContentType(const XsdComplexType::Ptr &complexType, bool effectiveMixed)
2883 {
2884  // @see http://www.w3.org/TR/xmlschema11-1/#dcl.ctd.ctcc.common
2885 
2886  // 1
2887  // the effectiveMixed contains the effective mixed value
2888 
2889  // 2
2890  bool hasEmptyContent = false;
2891  if (!complexType->contentType()->particle()) {
2892  hasEmptyContent = true; // 2.1.1
2893  } else {
2894  if (complexType->contentType()->particle()->term()->isModelGroup()) {
2895  const XsdModelGroup::Ptr group = complexType->contentType()->particle()->term();
2897  if (group->particles().isEmpty())
2898  hasEmptyContent = true; // 2.1.2
2899  } else if (group->compositor() == XsdModelGroup::ChoiceCompositor) {
2900  if ((complexType->contentType()->particle()->minimumOccurs() == 0) && group->particles().isEmpty())
2901  hasEmptyContent = true; // 2.1.3
2902  }
2903 
2904  if ((complexType->contentType()->particle()->maximumOccursUnbounded() == false) && (complexType->contentType()->particle()->maximumOccurs() == 0))
2905  hasEmptyContent = true; // 2.1.4
2906  }
2907  }
2908 
2909  const XsdParticle::Ptr explicitContent = (hasEmptyContent ? XsdParticle::Ptr() : complexType->contentType()->particle());
2910 
2911  // do all the other work (3, 4, 5 and 6) in the resolver, as they need access to the base type object
2912  m_schemaResolver->addComplexContentType(complexType, explicitContent, effectiveMixed);
2913 }
2914 
2916 {
2917  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::SimpleContent, this);
2918 
2920 
2921  complexType->contentType()->setVariety(XsdComplexType::ContentType::Simple);
2922 
2923  // parse attributes
2924  validateIdAttribute("simpleContent");
2925 
2927 
2928  while (!atEnd()) {
2929  readNext();
2930 
2931  if (isEndElement())
2932  break;
2933 
2934  if (isStartElement()) {
2937 
2938  tagValidator.validate(token);
2939 
2940  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
2941  const XsdAnnotation::Ptr annotation = parseAnnotation();
2942  complexType->addAnnotation(annotation);
2943  } else if (isSchemaTag(XsdSchemaToken::Restriction, token, namespaceToken)) {
2944  parseSimpleContentRestriction(complexType);
2945  } else if (isSchemaTag(XsdSchemaToken::Extension, token, namespaceToken)) {
2946  parseSimpleContentExtension(complexType);
2947  } else {
2948  parseUnknown();
2949  }
2950  }
2951  }
2952 
2953  tagValidator.finalize();
2954 }
2955 
2957 {
2958  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Restriction, this);
2959 
2961 
2963 
2964  // parse attributes
2965  const QString baseType = readQNameAttribute(QString::fromLatin1("base"), "restriction");
2967  convertName(baseType, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName
2968 
2969  validateIdAttribute("restriction");
2970 
2971  XsdFacet::Hash facets;
2972  QList<XsdFacet::Ptr> patternFacets;
2973  QList<XsdFacet::Ptr> enumerationFacets;
2974  QList<XsdFacet::Ptr> assertionFacets;
2975 
2977 
2978  while (!atEnd()) {
2979  readNext();
2980 
2981  if (isEndElement())
2982  break;
2983 
2984  if (isStartElement()) {
2987 
2988  tagValidator.validate(token);
2989 
2990  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
2991  const XsdAnnotation::Ptr annotation = parseAnnotation();
2992  complexType->addAnnotation(annotation);
2993  } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
2995  type->setContext(complexType); //TODO: investigate what the schema spec really wants here?!?
2996  complexType->contentType()->setSimpleType(type);
2997 
2998  // add it to list of anonymous types as well
2999  addAnonymousType(type);
3000  } else if (isSchemaTag(XsdSchemaToken::MinExclusive, token, namespaceToken)) {
3001  const XsdFacet::Ptr facet = parseMinExclusiveFacet();
3002  addFacet(facet, facets, complexType);
3003  } else if (isSchemaTag(XsdSchemaToken::MinInclusive, token, namespaceToken)) {
3004  const XsdFacet::Ptr facet = parseMinInclusiveFacet();
3005  addFacet(facet, facets, complexType);
3006  } else if (isSchemaTag(XsdSchemaToken::MaxExclusive, token, namespaceToken)) {
3007  const XsdFacet::Ptr facet = parseMaxExclusiveFacet();
3008  addFacet(facet, facets, complexType);
3009  } else if (isSchemaTag(XsdSchemaToken::MaxInclusive, token, namespaceToken)) {
3010  const XsdFacet::Ptr facet = parseMaxInclusiveFacet();
3011  addFacet(facet, facets, complexType);
3012  } else if (isSchemaTag(XsdSchemaToken::TotalDigits, token, namespaceToken)) {
3013  const XsdFacet::Ptr facet = parseTotalDigitsFacet();
3014  addFacet(facet, facets, complexType);
3015  } else if (isSchemaTag(XsdSchemaToken::FractionDigits, token, namespaceToken)) {
3016  const XsdFacet::Ptr facet = parseFractionDigitsFacet();
3017  addFacet(facet, facets, complexType);
3018  } else if (isSchemaTag(XsdSchemaToken::Length, token, namespaceToken)) {
3019  const XsdFacet::Ptr facet = parseLengthFacet();
3020  addFacet(facet, facets, complexType);
3021  } else if (isSchemaTag(XsdSchemaToken::MinLength, token, namespaceToken)) {
3022  const XsdFacet::Ptr facet = parseMinLengthFacet();
3023  addFacet(facet, facets, complexType);
3024  } else if (isSchemaTag(XsdSchemaToken::MaxLength, token, namespaceToken)) {
3025  const XsdFacet::Ptr facet = parseMaxLengthFacet();
3026  addFacet(facet, facets, complexType);
3027  } else if (isSchemaTag(XsdSchemaToken::Enumeration, token, namespaceToken)) {
3028  const XsdFacet::Ptr facet = parseEnumerationFacet();
3029  enumerationFacets.append(facet);
3030  } else if (isSchemaTag(XsdSchemaToken::WhiteSpace, token, namespaceToken)) {
3031  const XsdFacet::Ptr facet = parseWhiteSpaceFacet();
3032  addFacet(facet, facets, complexType);
3033  } else if (isSchemaTag(XsdSchemaToken::Pattern, token, namespaceToken)) {
3034  const XsdFacet::Ptr facet = parsePatternFacet();
3035  patternFacets.append(facet);
3036  } else if (isSchemaTag(XsdSchemaToken::Assertion, token, namespaceToken)) {
3037  const XsdFacet::Ptr facet = parseAssertionFacet();
3038  assertionFacets.append(facet);
3039  } else if (isSchemaTag(XsdSchemaToken::Attribute, token, namespaceToken)) {
3040  const XsdAttributeUse::Ptr attributeUse = parseLocalAttribute(complexType);
3041  complexType->addAttributeUse(attributeUse);
3042  } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) {
3043  const XsdAttributeUse::Ptr attributeUse = parseReferredAttributeGroup();
3044  complexType->addAttributeUse(attributeUse);
3045  } else if (isSchemaTag(XsdSchemaToken::AnyAttribute, token, namespaceToken)) {
3046  const XsdWildcard::Ptr wildcard = parseAnyAttribute();
3047  complexType->setAttributeWildcard(wildcard);
3048  } else if (isSchemaTag(XsdSchemaToken::Assert, token, namespaceToken)) {
3050  complexType->addAssertion(assertion);
3051  } else {
3052  parseUnknown();
3053  }
3054  }
3055  }
3056 
3057  tagValidator.finalize();
3058 
3059  // merge all pattern facets into one multi value facet
3060  if (!patternFacets.isEmpty()) {
3061  const XsdFacet::Ptr patternFacet(new XsdFacet());
3062  patternFacet->setType(XsdFacet::Pattern);
3063 
3064  AtomicValue::List multiValue;
3065  for (int i = 0; i < patternFacets.count(); ++i)
3066  multiValue << patternFacets.at(i)->multiValue();
3067 
3068  patternFacet->setMultiValue(multiValue);
3069  addFacet(patternFacet, facets, complexType);
3070  }
3071 
3072  // merge all enumeration facets into one multi value facet
3073  if (!enumerationFacets.isEmpty()) {
3074  const XsdFacet::Ptr enumerationFacet(new XsdFacet());
3075  enumerationFacet->setType(XsdFacet::Enumeration);
3076 
3077  AtomicValue::List multiValue;
3078  for (int i = 0; i < enumerationFacets.count(); ++i)
3079  multiValue << enumerationFacets.at(i)->multiValue();
3080 
3081  enumerationFacet->setMultiValue(multiValue);
3082  addFacet(enumerationFacet, facets, complexType);
3083  }
3084 
3085  // merge all assertion facets into one facet
3086  if (!assertionFacets.isEmpty()) {
3087  const XsdFacet::Ptr assertionFacet(new XsdFacet());
3088  assertionFacet->setType(XsdFacet::Assertion);
3089 
3090  XsdAssertion::List assertions;
3091  for (int i = 0; i < assertionFacets.count(); ++i)
3092  assertions << assertionFacets.at(i)->assertions();
3093 
3094  assertionFacet->setAssertions(assertions);
3095  addFacet(assertionFacet, facets, complexType);
3096  }
3097 
3098  m_schemaResolver->addComplexBaseType(complexType, typeName, currentSourceLocation(), facets); // add to resolver
3099 }
3100 
3102 {
3103  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Extension, this);
3104 
3106 
3108 
3109  // parse attributes
3110  const QString baseType = readQNameAttribute(QString::fromLatin1("base"), "extension");
3112  convertName(baseType, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName
3113  m_schemaResolver->addComplexBaseType(complexType, typeName, currentSourceLocation()); // add to resolver
3114 
3115  validateIdAttribute("extension");
3116 
3118 
3119  while (!atEnd()) {
3120  readNext();
3121 
3122  if (isEndElement())
3123  break;
3124 
3125  if (isStartElement()) {
3128 
3129  tagValidator.validate(token);
3130 
3131  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
3132  const XsdAnnotation::Ptr annotation = parseAnnotation();
3133  complexType->addAnnotation(annotation);
3134  } else if (isSchemaTag(XsdSchemaToken::Attribute, token, namespaceToken)) {
3135  const XsdAttributeUse::Ptr attributeUse = parseLocalAttribute(complexType);
3136  complexType->addAttributeUse(attributeUse);
3137  } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) {
3138  const XsdAttributeUse::Ptr attributeUse = parseReferredAttributeGroup();
3139  complexType->addAttributeUse(attributeUse);
3140  } else if (isSchemaTag(XsdSchemaToken::AnyAttribute, token, namespaceToken)) {
3141  const XsdWildcard::Ptr wildcard = parseAnyAttribute();
3142  complexType->setAttributeWildcard(wildcard);
3143  } else if (isSchemaTag(XsdSchemaToken::Assert, token, namespaceToken)) {
3145  complexType->addAssertion(assertion);
3146  } else {
3147  parseUnknown();
3148  }
3149  }
3150  }
3151 
3152  tagValidator.finalize();
3153 }
3154 
3155 void XsdSchemaParser::parseComplexContent(const XsdComplexType::Ptr &complexType, bool *mixed)
3156 {
3157  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::ComplexContent, this);
3158 
3160 
3161  complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
3162 
3163  // parse attributes
3164  if (hasAttribute(QString::fromLatin1("mixed"))) {
3165  const QString mixedStr = readAttribute(QString::fromLatin1("mixed"));
3166 
3167  const Boolean::Ptr value = Boolean::fromLexical(mixedStr);
3168  if (value->hasError()) {
3169  attributeContentError("mixed", "complexType", mixedStr, BuiltinTypes::xsBoolean);
3170  return;
3171  }
3172 
3173  *mixed = value->as<Boolean>()->value();
3174  } else {
3175  *mixed = false;
3176  }
3177 
3178  validateIdAttribute("complexContent");
3179 
3181 
3182  while (!atEnd()) {
3183  readNext();
3184 
3185  if (isEndElement())
3186  break;
3187 
3188  if (isStartElement()) {
3191 
3192  tagValidator.validate(token);
3193 
3194  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
3195  const XsdAnnotation::Ptr annotation = parseAnnotation();
3196  complexType->addAnnotation(annotation);
3197  } else if (isSchemaTag(XsdSchemaToken::Restriction, token, namespaceToken)) {
3198  parseComplexContentRestriction(complexType);
3199  } else if (isSchemaTag(XsdSchemaToken::Extension, token, namespaceToken)) {
3200  parseComplexContentExtension(complexType);
3201  } else {
3202  parseUnknown();
3203  }
3204  }
3205  }
3206 
3207  tagValidator.finalize();
3208 }
3209 
3211 {
3212  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Restriction, this);
3213 
3215 
3217 
3218  // parse attributes
3219  const QString baseType = readQNameAttribute(QString::fromLatin1("base"), "restriction");
3221  convertName(baseType, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName
3222  m_schemaResolver->addComplexBaseType(complexType, typeName, currentSourceLocation()); // add to resolver
3223 
3224  validateIdAttribute("restriction");
3225 
3227 
3228  bool hasContent = false;
3229  while (!atEnd()) {
3230  readNext();
3231 
3232  if (isEndElement())
3233  break;
3234 
3235  if (isStartElement()) {
3238 
3239  tagValidator.validate(token);
3240 
3241  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
3242  const XsdAnnotation::Ptr annotation = parseAnnotation();
3243  complexType->addAnnotation(annotation);
3244  } else if (isSchemaTag(XsdSchemaToken::OpenContent, token, namespaceToken)) {
3245  const XsdComplexType::OpenContent::Ptr openContent = parseOpenContent();
3246  complexType->contentType()->setOpenContent(openContent);
3247  hasContent = true;
3248  } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) {
3249  const XsdParticle::Ptr particle(new XsdParticle());
3250  const XsdTerm::Ptr term = parseReferredGroup(particle);
3251  particle->setTerm(term);
3252  complexType->contentType()->setParticle(particle);
3253  hasContent = true;
3254  } else if (isSchemaTag(XsdSchemaToken::All, token, namespaceToken)) {
3255  const XsdParticle::Ptr particle(new XsdParticle());
3256  const XsdTerm::Ptr term = parseLocalAll(particle, complexType);
3257  particle->setTerm(term);
3258  complexType->contentType()->setParticle(particle);
3259  hasContent = true;
3260  } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) {
3261  const XsdParticle::Ptr particle(new XsdParticle());
3262  const XsdTerm::Ptr term = parseLocalChoice(particle, complexType);
3263  particle->setTerm(term);
3264  complexType->contentType()->setParticle(particle);
3265  hasContent = true;
3266  } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) {
3267  const XsdParticle::Ptr particle(new XsdParticle());
3268  const XsdTerm::Ptr term = parseLocalSequence(particle, complexType);
3269  particle->setTerm(term);
3270  complexType->contentType()->setParticle(particle);
3271  hasContent = true;
3272  } else if (isSchemaTag(XsdSchemaToken::Attribute, token, namespaceToken)) {
3273  const XsdAttributeUse::Ptr attributeUse = parseLocalAttribute(complexType);
3274  complexType->addAttributeUse(attributeUse);
3275  } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) {
3276  const XsdAttributeUse::Ptr attributeUse = parseReferredAttributeGroup();
3277  complexType->addAttributeUse(attributeUse);
3278  } else if (isSchemaTag(XsdSchemaToken::AnyAttribute, token, namespaceToken)) {
3279  const XsdWildcard::Ptr wildcard = parseAnyAttribute();
3280  complexType->setAttributeWildcard(wildcard);
3281  } else if (isSchemaTag(XsdSchemaToken::Assert, token, namespaceToken)) {
3283  complexType->addAssertion(assertion);
3284  } else {
3285  parseUnknown();
3286  }
3287  }
3288  }
3289 
3290  if (!hasContent)
3291  complexType->contentType()->setVariety(XsdComplexType::ContentType::Empty);
3292 
3293  tagValidator.finalize();
3294 }
3295 
3297 {
3298  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Extension, this);
3299 
3301 
3303 
3304  // parse attributes
3305  const QString baseType = readQNameAttribute(QString::fromLatin1("base"), "extension");
3307  convertName(baseType, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName
3308  m_schemaResolver->addComplexBaseType(complexType, typeName, currentSourceLocation()); // add to resolver
3309 
3310  validateIdAttribute("extension");
3311 
3313 
3314  bool hasContent = false;
3315  while (!atEnd()) {
3316  readNext();
3317 
3318  if (isEndElement())
3319  break;
3320 
3321  if (isStartElement()) {
3324 
3325  tagValidator.validate(token);
3326 
3327  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
3328  const XsdAnnotation::Ptr annotation = parseAnnotation();
3329  complexType->addAnnotation(annotation);
3330  } else if (isSchemaTag(XsdSchemaToken::OpenContent, token, namespaceToken)) {
3331  const XsdComplexType::OpenContent::Ptr openContent = parseOpenContent();
3332  complexType->contentType()->setOpenContent(openContent);
3333  hasContent = true;
3334  } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) {
3335  const XsdParticle::Ptr particle(new XsdParticle());
3336  const XsdTerm::Ptr term = parseReferredGroup(particle);
3337  particle->setTerm(term);
3338  complexType->contentType()->setParticle(particle);
3339  hasContent = true;
3340  } else if (isSchemaTag(XsdSchemaToken::All, token, namespaceToken)) {
3341  const XsdParticle::Ptr particle(new XsdParticle());
3342  const XsdTerm::Ptr term = parseLocalAll(particle, complexType);
3343  particle->setTerm(term);
3344  complexType->contentType()->setParticle(particle);
3345  hasContent = true;
3346  } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) {
3347  const XsdParticle::Ptr particle(new XsdParticle());
3348  const XsdTerm::Ptr term = parseLocalChoice(particle, complexType);
3349  particle->setTerm(term);
3350  complexType->contentType()->setParticle(particle);
3351  hasContent = true;
3352  } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) {
3353  const XsdParticle::Ptr particle(new XsdParticle());
3354  const XsdTerm::Ptr term = parseLocalSequence(particle, complexType);
3355  particle->setTerm(term);
3356  complexType->contentType()->setParticle(particle);
3357  hasContent = true;
3358  } else if (isSchemaTag(XsdSchemaToken::Attribute, token, namespaceToken)) {
3359  const XsdAttributeUse::Ptr attributeUse = parseLocalAttribute(complexType);
3360  complexType->addAttributeUse(attributeUse);
3361  } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) {
3362  const XsdAttributeUse::Ptr attributeUse = parseReferredAttributeGroup();
3363  complexType->addAttributeUse(attributeUse);
3364  } else if (isSchemaTag(XsdSchemaToken::AnyAttribute, token, namespaceToken)) {
3365  const XsdWildcard::Ptr wildcard = parseAnyAttribute();
3366  complexType->setAttributeWildcard(wildcard);
3367  } else if (isSchemaTag(XsdSchemaToken::Assert, token, namespaceToken)) {
3369  complexType->addAssertion(assertion);
3370  } else {
3371  parseUnknown();
3372  }
3373  }
3374  }
3375 
3376  if (!hasContent)
3377  complexType->contentType()->setVariety(XsdComplexType::ContentType::Empty);
3378 
3379  tagValidator.finalize();
3380 }
3381 
3382 
3384 {
3385  const ElementNamespaceHandler namespaceHandler(nodeName, this);
3386 
3387  validateElement(tag);
3388 
3389  const XsdAssertion::Ptr assertion(new XsdAssertion());
3390 
3391  // parse attributes
3392 
3393  const XsdXPathExpression::Ptr expression = readXPathExpression("assertion");
3394  assertion->setTest(expression);
3395 
3396  const QString test = readXPathAttribute(QString::fromLatin1("test"), XPath20, "assertion");
3397  expression->setExpression(test);
3398 
3399  validateIdAttribute("assertion");
3400 
3401  TagValidationHandler tagValidator(tag, this, NamePool::Ptr(m_namePool));
3402 
3403  while (!atEnd()) {
3404  readNext();
3405 
3406  if (isEndElement())
3407  break;
3408 
3409  if (isStartElement()) {
3412 
3413  tagValidator.validate(token);
3414 
3415  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
3416  const XsdAnnotation::Ptr annotation = parseAnnotation();
3417  assertion->addAnnotation(annotation);
3418  } else {
3419  parseUnknown();
3420  }
3421  }
3422  }
3423 
3424  tagValidator.finalize();
3425 
3426  return assertion;
3427 }
3428 
3430 {
3431  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::OpenContent, this);
3432 
3434 
3436 
3437  if (hasAttribute(QString::fromLatin1("mode"))) {
3438  const QString mode = readAttribute(QString::fromLatin1("mode"));
3439 
3440  if (mode == QString::fromLatin1("none")) {
3442  } else if (mode == QString::fromLatin1("interleave")) {
3444  } else if (mode == QString::fromLatin1("suffix")) {
3446  } else {
3447  attributeContentError("mode", "openContent", mode);
3448  return openContent;
3449  }
3450  } else {
3451  openContent->setMode(XsdComplexType::OpenContent::Interleave);
3452  }
3453 
3454  validateIdAttribute("openContent");
3455 
3457 
3458  while (!atEnd()) {
3459  readNext();
3460 
3461  if (isEndElement())
3462  break;
3463 
3464  if (isStartElement()) {
3467 
3468  tagValidator.validate(token);
3469 
3470  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
3471  const XsdAnnotation::Ptr annotation = parseAnnotation();
3472  openContent->addAnnotation(annotation);
3473  } else if (isSchemaTag(XsdSchemaToken::Any, token, namespaceToken)) {
3474  const XsdParticle::Ptr particle;
3475  const XsdWildcard::Ptr wildcard = parseAny(particle);
3476  openContent->setWildcard(wildcard);
3477  } else {
3478  parseUnknown();
3479  }
3480  }
3481  }
3482 
3483  tagValidator.finalize();
3484 
3485  return openContent;
3486 }
3487 
3489 {
3490  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Group, this);
3491 
3493 
3494  const XsdModelGroup::Ptr modelGroup(new XsdModelGroup());
3495  XsdModelGroup::Ptr group;
3496 
3497  QXmlName objectName;
3498  if (hasAttribute(QString::fromLatin1("name"))) {
3500  }
3501 
3502  validateIdAttribute("group");
3503 
3505 
3506  XsdAnnotation::Ptr annotation;
3507 
3508  while (!atEnd()) {
3509  readNext();
3510 
3511  if (isEndElement())
3512  break;
3513 
3514  if (isStartElement()) {
3517 
3518  tagValidator.validate(token);
3519 
3520  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
3521  annotation = parseAnnotation();
3522  } else if (isSchemaTag(XsdSchemaToken::All, token, namespaceToken)) {
3523  group = parseAll(modelGroup);
3524  } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) {
3525  group = parseChoice(modelGroup);
3526  } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) {
3527  group = parseSequence(modelGroup);
3528  } else {
3529  parseUnknown();
3530  }
3531  }
3532  }
3533 
3534  tagValidator.finalize();
3535 
3536  group->setName(objectName);
3537 
3538  if (annotation)
3539  group->addAnnotation(annotation);
3540 
3541  return group;
3542 }
3543 
3545 {
3546  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Group, this);
3547 
3549 
3550  const XsdReference::Ptr reference(new XsdReference());
3551  reference->setType(XsdReference::ModelGroup);
3552  reference->setSourceLocation(currentSourceLocation());
3553 
3554  // parse attributes
3555  if (!parseMinMaxConstraint(particle, "group")) {
3556  return reference;
3557  }
3558 
3559  const QString value = readQNameAttribute(QString::fromLatin1("ref"), "group");
3560  QXmlName referenceName;
3561  convertName(value, NamespaceSupport::ElementName, referenceName); // translate qualified name into QXmlName
3562  reference->setReferenceName(referenceName);
3563 
3564  validateIdAttribute("group");
3565 
3567 
3568  while (!atEnd()) {
3569  readNext();
3570 
3571  if (isEndElement())
3572  break;
3573 
3574  if (isStartElement()) {
3577 
3578  tagValidator.validate(token);
3579 
3580  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
3581  const XsdAnnotation::Ptr annotation = parseAnnotation();
3582  reference->addAnnotation(annotation);
3583  } else {
3584  parseUnknown();
3585  }
3586  }
3587  }
3588 
3589  tagValidator.finalize();
3590 
3591  return reference;
3592 }
3593 
3595 {
3596  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::All, this);
3597 
3599 
3600  const XsdModelGroup::Ptr modelGroup(new XsdModelGroup());
3602 
3603  validateIdAttribute("all");
3604 
3606 
3607  XsdParticle::List particles;
3608  while (!atEnd()) {
3609  readNext();
3610 
3611  if (isEndElement())
3612  break;
3613 
3614  if (isStartElement()) {
3617 
3618  tagValidator.validate(token);
3619 
3620  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
3621  const XsdAnnotation::Ptr annotation = parseAnnotation();
3622  modelGroup->addAnnotation(annotation);
3623  } else if (isSchemaTag(XsdSchemaToken::Element, token, namespaceToken)) {
3624  const XsdParticle::Ptr particle(new XsdParticle());
3625  const XsdTerm::Ptr term = parseLocalElement(particle, parent);
3626  particle->setTerm(term);
3627 
3628  if (particle->maximumOccursUnbounded() || particle->maximumOccurs() > 1) {
3629  error(QtXmlPatterns::tr("%1 attribute of %2 element must be %3 or %4.")
3630  .arg(formatAttribute("maxOccurs"))
3631  .arg(formatElement("all"))
3632  .arg(formatData("0"))
3633  .arg(formatData("1")));
3634  return modelGroup;
3635  }
3636 
3637  particles.append(particle);
3638  } else {
3639  parseUnknown();
3640  }
3641  }
3642  }
3643 
3644  modelGroup->setParticles(particles);
3645 
3646  tagValidator.finalize();
3647 
3648  return modelGroup;
3649 }
3650 
3652 {
3653  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::All, this);
3654 
3656 
3657  const XsdModelGroup::Ptr modelGroup(new XsdModelGroup());
3659 
3660  // parse attributes
3661  if (!parseMinMaxConstraint(particle, "all")) {
3662  return modelGroup;
3663  }
3664  if (particle->maximumOccursUnbounded() || particle->maximumOccurs() != 1) {
3665  error(QtXmlPatterns::tr("%1 attribute of %2 element must have a value of %3.")
3666  .arg(formatAttribute("maxOccurs"))
3667  .arg(formatElement("all"))
3668  .arg(formatData("1")));
3669  return modelGroup;
3670  }
3671  if (particle->minimumOccurs() != 0 && particle->minimumOccurs() != 1) {
3672  error(QtXmlPatterns::tr("%1 attribute of %2 element must have a value of %3 or %4.")
3673  .arg(formatAttribute("minOccurs"))
3674  .arg(formatElement("all"))
3675  .arg(formatData("0"))
3676  .arg(formatData("1")));
3677  return modelGroup;
3678  }
3679 
3680  validateIdAttribute("all");
3681 
3683 
3684  XsdParticle::List particles;
3685  while (!atEnd()) {
3686  readNext();
3687 
3688  if (isEndElement())
3689  break;
3690 
3691  if (isStartElement()) {
3694 
3695  tagValidator.validate(token);
3696 
3697  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
3698  const XsdAnnotation::Ptr annotation = parseAnnotation();
3699  modelGroup->addAnnotation(annotation);
3700  } else if (isSchemaTag(XsdSchemaToken::Element, token, namespaceToken)) {
3701  const XsdParticle::Ptr particle(new XsdParticle());
3702  const XsdTerm::Ptr term = parseLocalElement(particle, parent);
3703  particle->setTerm(term);
3704 
3705  if (particle->maximumOccursUnbounded() || particle->maximumOccurs() > 1) {
3706  error(QtXmlPatterns::tr("%1 attribute of %2 element must have a value of %3 or %4.")
3707  .arg(formatAttribute("maxOccurs"))
3708  .arg(formatElement("all"))
3709  .arg(formatData("0"))
3710  .arg(formatData("1")));
3711  return modelGroup;
3712  }
3713 
3714  particles.append(particle);
3715  } else {
3716  parseUnknown();
3717  }
3718  }
3719  }
3720 
3721  modelGroup->setParticles(particles);
3722 
3723  tagValidator.finalize();
3724 
3725  return modelGroup;
3726 }
3727 
3729 {
3730  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Choice, this);
3731 
3733 
3734  const XsdModelGroup::Ptr modelGroup(new XsdModelGroup());
3736 
3737  validateIdAttribute("choice");
3738 
3739  XsdParticle::List particles;
3740 
3742 
3743  while (!atEnd()) {
3744  readNext();
3745 
3746  if (isEndElement())
3747  break;
3748 
3749  if (isStartElement()) {
3752 
3753  tagValidator.validate(token);
3754 
3755  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
3756  const XsdAnnotation::Ptr annotation = parseAnnotation();
3757  modelGroup->addAnnotation(annotation);
3758  } else if (isSchemaTag(XsdSchemaToken::Element, token, namespaceToken)) {
3759  const XsdParticle::Ptr particle(new XsdParticle());
3760  const XsdTerm::Ptr term = parseLocalElement(particle, parent);
3761  particle->setTerm(term);
3762  particles.append(particle);
3763  } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) {
3764  const XsdParticle::Ptr particle(new XsdParticle());
3765  const XsdTerm::Ptr term = parseReferredGroup(particle);
3767  particle->setTerm(term);
3768  particles.append(particle);
3769  } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) {
3770  const XsdParticle::Ptr particle(new XsdParticle());
3771  const XsdTerm::Ptr term = parseLocalChoice(particle, parent);
3772  particle->setTerm(term);
3773  particles.append(particle);
3774  } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) {
3775  const XsdParticle::Ptr particle(new XsdParticle());
3776  const XsdTerm::Ptr term = parseLocalSequence(particle, parent);
3777  particle->setTerm(term);
3778  particles.append(particle);
3779  } else if (isSchemaTag(XsdSchemaToken::Any, token, namespaceToken)) {
3780  const XsdParticle::Ptr particle(new XsdParticle());
3781  const XsdTerm::Ptr term = parseAny(particle);
3782  particle->setTerm(term);
3783  particles.append(particle);
3784  } else {
3785  parseUnknown();
3786  }
3787  }
3788  }
3789 
3790  modelGroup->setParticles(particles);
3791 
3792  tagValidator.finalize();
3793 
3794  return modelGroup;
3795 }
3796 
3798 {
3799  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Choice, this);
3800 
3802 
3803  const XsdModelGroup::Ptr modelGroup(new XsdModelGroup());
3805 
3806  // parse attributes
3807  if (!parseMinMaxConstraint(particle, "choice")) {
3808  return modelGroup;
3809  }
3810 
3811  validateIdAttribute("choice");
3812 
3813  XsdParticle::List particles;
3814 
3816 
3817  while (!atEnd()) {
3818  readNext();
3819 
3820  if (isEndElement())
3821  break;
3822 
3823  if (isStartElement()) {
3826 
3827  tagValidator.validate(token);
3828 
3829  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
3830  const XsdAnnotation::Ptr annotation = parseAnnotation();
3831  modelGroup->addAnnotation(annotation);
3832  } else if (isSchemaTag(XsdSchemaToken::Element, token, namespaceToken)) {
3833  const XsdParticle::Ptr particle(new XsdParticle());
3834  const XsdTerm::Ptr term = parseLocalElement(particle, parent);
3835  particle->setTerm(term);
3836  particles.append(particle);
3837  } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) {
3838  const XsdParticle::Ptr particle(new XsdParticle());
3839  const XsdTerm::Ptr term = parseReferredGroup(particle);
3841  particle->setTerm(term);
3842  particles.append(particle);
3843  } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) {
3844  const XsdParticle::Ptr particle(new XsdParticle());
3845  const XsdTerm::Ptr term = parseLocalChoice(particle, parent);
3846  particle->setTerm(term);
3847  particles.append(particle);
3848  } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) {
3849  const XsdParticle::Ptr particle(new XsdParticle());
3850  const XsdTerm::Ptr term = parseLocalSequence(particle, parent);
3851  particle->setTerm(term);
3852  particles.append(particle);
3853  } else if (isSchemaTag(XsdSchemaToken::Any, token, namespaceToken)) {
3854  const XsdParticle::Ptr particle(new XsdParticle());
3855  const XsdTerm::Ptr term = parseAny(particle);
3856  particle->setTerm(term);
3857  particles.append(particle);
3858  } else {
3859  parseUnknown();
3860  }
3861  }
3862  }
3863 
3864  modelGroup->setParticles(particles);
3865 
3866  tagValidator.finalize();
3867 
3868  return modelGroup;
3869 }
3870 
3872 {
3873  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Sequence, this);
3874 
3876 
3877  const XsdModelGroup::Ptr modelGroup(new XsdModelGroup());
3879 
3880  validateIdAttribute("sequence");
3881 
3882  XsdParticle::List particles;
3883 
3885 
3886  while (!atEnd()) {
3887  readNext();
3888 
3889  if (isEndElement())
3890  break;
3891 
3892  if (isStartElement()) {
3895 
3896  tagValidator.validate(token);
3897 
3898  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
3899  const XsdAnnotation::Ptr annotation = parseAnnotation();
3900  modelGroup->addAnnotation(annotation);
3901  } else if (isSchemaTag(XsdSchemaToken::Element, token, namespaceToken)) {
3902  const XsdParticle::Ptr particle(new XsdParticle());
3903  const XsdTerm::Ptr term = parseLocalElement(particle, parent);
3904  particle->setTerm(term);
3905  particles.append(particle);
3906  } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) {
3907  const XsdParticle::Ptr particle(new XsdParticle());
3908  const XsdTerm::Ptr term = parseReferredGroup(particle);
3910  particle->setTerm(term);
3911  particles.append(particle);
3912  } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) {
3913  const XsdParticle::Ptr particle(new XsdParticle());
3914  const XsdTerm::Ptr term = parseLocalChoice(particle, parent);
3915  particle->setTerm(term);
3916  particles.append(particle);
3917  } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) {
3918  const XsdParticle::Ptr particle(new XsdParticle());
3919  const XsdTerm::Ptr term = parseLocalSequence(particle, parent);
3920  particle->setTerm(term);
3921  particles.append(particle);
3922  } else if (isSchemaTag(XsdSchemaToken::Any, token, namespaceToken)) {
3923  const XsdParticle::Ptr particle(new XsdParticle());
3924  const XsdTerm::Ptr term = parseAny(particle);
3925  particle->setTerm(term);
3926  particles.append(particle);
3927  } else {
3928  parseUnknown();
3929  }
3930  }
3931  }
3932 
3933  modelGroup->setParticles(particles);
3934 
3935  tagValidator.finalize();
3936 
3937  return modelGroup;
3938 }
3939 
3941 {
3942  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Sequence, this);
3943 
3945 
3946  const XsdModelGroup::Ptr modelGroup(new XsdModelGroup());
3948 
3949  // parse attributes
3950  if (!parseMinMaxConstraint(particle, "sequence")) {
3951  return modelGroup;
3952  }
3953 
3954  validateIdAttribute("sequence");
3955 
3956  XsdParticle::List particles;
3957 
3959 
3960  while (!atEnd()) {
3961  readNext();
3962 
3963  if (isEndElement())
3964  break;
3965 
3966  if (isStartElement()) {
3969 
3970  tagValidator.validate(token);
3971 
3972  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
3973  const XsdAnnotation::Ptr annotation = parseAnnotation();
3974  modelGroup->addAnnotation(annotation);
3975  } else if (isSchemaTag(XsdSchemaToken::Element, token, namespaceToken)) {
3976  const XsdParticle::Ptr particle(new XsdParticle());
3977  const XsdTerm::Ptr term = parseLocalElement(particle, parent);
3978  particle->setTerm(term);
3979  particles.append(particle);
3980  } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) {
3981  const XsdParticle::Ptr particle(new XsdParticle());
3982  const XsdTerm::Ptr term = parseReferredGroup(particle);
3984  particle->setTerm(term);
3985  particles.append(particle);
3986  } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) {
3987  const XsdParticle::Ptr particle(new XsdParticle());
3988  const XsdTerm::Ptr term = parseLocalChoice(particle, parent);
3989  particle->setTerm(term);
3990  particles.append(particle);
3991  } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) {
3992  const XsdParticle::Ptr particle(new XsdParticle());
3993  const XsdTerm::Ptr term = parseLocalSequence(particle, parent);
3994  particle->setTerm(term);
3995  particles.append(particle);
3996  } else if (isSchemaTag(XsdSchemaToken::Any, token, namespaceToken)) {
3997  const XsdParticle::Ptr particle(new XsdParticle());
3998  const XsdTerm::Ptr term = parseAny(particle);
3999  particle->setTerm(term);
4000  particles.append(particle);
4001  } else {
4002  parseUnknown();
4003  }
4004  }
4005  }
4006 
4007  modelGroup->setParticles(particles);
4008 
4009  tagValidator.finalize();
4010 
4011  return modelGroup;
4012 }
4013 
4015 {
4016  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Attribute, this);
4017 
4019 
4020  const XsdAttribute::Ptr attribute(new XsdAttribute());
4022  attribute->scope()->setVariety(XsdAttribute::Scope::Global);
4023 
4024  if (hasAttribute(QString::fromLatin1("default")) && hasAttribute(QString::fromLatin1("fixed"))) {
4025  error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
4026  .arg(formatElement("attribute"))
4027  .arg(formatAttribute("default"))
4028  .arg(formatAttribute("fixed")));
4029  return attribute;
4030  }
4031 
4032  // parse attributes
4033  if (hasAttribute(QString::fromLatin1("default"))) {
4034  const QString value = readAttribute(QString::fromLatin1("default"));
4036  attribute->valueConstraint()->setVariety(XsdAttribute::ValueConstraint::Default);
4037  attribute->valueConstraint()->setValue(value);
4038  } else if (hasAttribute(QString::fromLatin1("fixed"))) {
4039  const QString value = readAttribute(QString::fromLatin1("fixed"));
4041  attribute->valueConstraint()->setVariety(XsdAttribute::ValueConstraint::Fixed);
4042  attribute->valueConstraint()->setValue(value);
4043  }
4044 
4045  const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("attribute"));
4046  if ((objectName.namespaceURI() == StandardNamespaces::xsi) &&
4047  (m_namePool->stringForLocalName(objectName.localName()) != QString::fromLatin1("type")) &&
4048  (m_namePool->stringForLocalName(objectName.localName()) != QString::fromLatin1("nil")) &&
4049  (m_namePool->stringForLocalName(objectName.localName()) != QString::fromLatin1("schemaLocation")) &&
4050  (m_namePool->stringForLocalName(objectName.localName()) != QString::fromLatin1("noNamespaceSchemaLocation"))) {
4051 
4052  error(QtXmlPatterns::tr("Content of %1 attribute of %2 element must not be from namespace %3.")
4053  .arg(formatAttribute("name"))
4054  .arg(formatElement("attribute"))
4056  return attribute;
4057  }
4058  if (m_namePool->stringForLocalName(objectName.localName()) == QString::fromLatin1("xmlns")) {
4059  error(QtXmlPatterns::tr("%1 attribute of %2 element must not be %3.")
4060  .arg(formatAttribute("name"))
4061  .arg(formatElement("attribute"))
4062  .arg(formatData("xmlns")));
4063  return attribute;
4064  }
4065  attribute->setName(objectName);
4066 
4067  bool hasTypeAttribute = false;
4068  bool hasTypeSpecified = false;
4069 
4070  if (hasAttribute(QString::fromLatin1("type"))) {
4071  hasTypeAttribute = true;
4072 
4073  const QString type = readQNameAttribute(QString::fromLatin1("type"), "attribute");
4075  convertName(type, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName
4076  m_schemaResolver->addAttributeType(attribute, typeName, currentSourceLocation()); // add to resolver
4077  hasTypeSpecified = true;
4078  }
4079 
4080  validateIdAttribute("attribute");
4081 
4083 
4084  while (!atEnd()) {
4085  readNext();
4086 
4087  if (isEndElement())
4088  break;
4089 
4090  if (isStartElement()) {
4093 
4094  tagValidator.validate(token);
4095 
4096  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
4097  const XsdAnnotation::Ptr annotation = parseAnnotation();
4098  attribute->addAnnotation(annotation);
4099  } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
4100  if (hasTypeAttribute) {
4101  error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
4102  .arg(formatElement("attribute"))
4103  .arg(formatElement("simpleType"))
4104  .arg(formatAttribute("type")));
4105  break;
4106  }
4107 
4109  type->setContext(attribute);
4110  attribute->setType(type);
4111  hasTypeSpecified = true;
4112 
4113  // add it to list of anonymous types as well
4114  addAnonymousType(type);
4115  } else {
4116  parseUnknown();
4117  }
4118  }
4119  }
4120 
4121  if (!hasTypeSpecified) {
4122  attribute->setType(BuiltinTypes::xsAnySimpleType); // default value
4123  return attribute;
4124  }
4125 
4126  tagValidator.finalize();
4127 
4128  return attribute;
4129 }
4130 
4132 {
4133  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Attribute, this);
4134 
4136 
4137  bool hasRefAttribute = false;
4138  bool hasTypeAttribute = false;
4139  bool hasTypeSpecified = false;
4140 
4141  XsdAttributeUse::Ptr attributeUse;
4142  if (hasAttribute(QString::fromLatin1("ref"))) {
4144  reference->setType(XsdAttributeReference::AttributeUse);
4145  reference->setSourceLocation(currentSourceLocation());
4146 
4147  attributeUse = reference;
4148  hasRefAttribute = true;
4149  } else {
4150  attributeUse = XsdAttributeUse::Ptr(new XsdAttributeUse());
4151  }
4152 
4153  if (hasAttribute(QString::fromLatin1("default")) && hasAttribute(QString::fromLatin1("fixed"))) {
4154  error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
4155  .arg(formatElement("attribute"))
4156  .arg(formatAttribute("default"))
4157  .arg(formatAttribute("fixed")));
4158  return attributeUse;
4159  }
4160 
4161  if (hasRefAttribute) {
4162  if (hasAttribute(QString::fromLatin1("form"))) {
4163  error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
4164  .arg(formatElement("attribute"))
4165  .arg(formatAttribute("ref"))
4166  .arg(formatAttribute("form")));
4167  return attributeUse;
4168  }
4169  if (hasAttribute(QString::fromLatin1("name"))) {
4170  error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
4171  .arg(formatElement("attribute"))
4172  .arg(formatAttribute("ref"))
4173  .arg(formatAttribute("name")));
4174  return attributeUse;
4175  }
4176  if (hasAttribute(QString::fromLatin1("type"))) {
4177  error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
4178  .arg(formatElement("attribute"))
4179  .arg(formatAttribute("ref"))
4180  .arg(formatAttribute("type")));
4181  return attributeUse;
4182  }
4183  }
4184 
4185  // parse attributes
4186 
4187  // default, fixed and use are handled by both, attribute use and attribute reference
4188  if (hasAttribute(QString::fromLatin1("default"))) {
4189  const QString value = readAttribute(QString::fromLatin1("default"));
4190  attributeUse->setValueConstraint(XsdAttributeUse::ValueConstraint::Ptr(new XsdAttributeUse::ValueConstraint()));
4191  attributeUse->valueConstraint()->setVariety(XsdAttributeUse::ValueConstraint::Default);
4192  attributeUse->valueConstraint()->setValue(value);
4193  } else if (hasAttribute(QString::fromLatin1("fixed"))) {
4194  const QString value = readAttribute(QString::fromLatin1("fixed"));
4195  attributeUse->setValueConstraint(XsdAttributeUse::ValueConstraint::Ptr(new XsdAttributeUse::ValueConstraint()));
4196  attributeUse->valueConstraint()->setVariety(XsdAttributeUse::ValueConstraint::Fixed);
4197  attributeUse->valueConstraint()->setValue(value);
4198  }
4199 
4200  if (hasAttribute(QString::fromLatin1("use"))) {
4201  const QString value = readAttribute(QString::fromLatin1("use"));
4202  if (value != QString::fromLatin1("optional") &&
4203  value != QString::fromLatin1("prohibited") &&
4204  value != QString::fromLatin1("required")) {
4205  attributeContentError("use", "attribute", value);
4206  return attributeUse;
4207  }
4208 
4209  if (value == QString::fromLatin1("optional"))
4210  attributeUse->setUseType(XsdAttributeUse::OptionalUse);
4211  else if (value == QString::fromLatin1("prohibited"))
4212  attributeUse->setUseType(XsdAttributeUse::ProhibitedUse);
4213  else if (value == QString::fromLatin1("required"))
4214  attributeUse->setUseType(XsdAttributeUse::RequiredUse);
4215 
4216  if (attributeUse->valueConstraint() && attributeUse->valueConstraint()->variety() == XsdAttributeUse::ValueConstraint::Default && value != QString::fromLatin1("optional")) {
4217  error(QtXmlPatterns::tr("%1 attribute of %2 element must have the value %3 because the %4 attribute is set.")
4218  .arg(formatAttribute("use"))
4219  .arg(formatElement("attribute"))
4220  .arg(formatData("optional"))
4221  .arg(formatElement("default")));
4222  return attributeUse;
4223  }
4224  }
4225 
4226  const XsdAttribute::Ptr attribute(new XsdAttribute());
4227 
4228  attributeUse->setAttribute(attribute);
4230 
4232  attribute->scope()->setVariety(XsdAttribute::Scope::Local);
4233  attribute->scope()->setParent(parent);
4234 
4235  // now make a difference between attribute reference and attribute use
4236  if (hasRefAttribute) {
4237  const QString reference = readQNameAttribute(QString::fromLatin1("ref"), "attribute");
4238  QXmlName referenceName;
4239  convertName(reference, NamespaceSupport::ElementName, referenceName); // translate qualified name into QXmlName
4240 
4241  const XsdAttributeReference::Ptr attributeReference = attributeUse;
4242  attributeReference->setReferenceName(referenceName);
4243  } else {
4244  if (hasAttribute(QString::fromLatin1("name"))) {
4245  const QString attributeName = readNameAttribute("attribute");
4246 
4247  QXmlName objectName;
4248  if (hasAttribute(QString::fromLatin1("form"))) {
4249  const QString value = readAttribute(QString::fromLatin1("form"));
4250  if (value != QString::fromLatin1("qualified") && value != QString::fromLatin1("unqualified")) {
4251  attributeContentError("form", "attribute", value);
4252  return attributeUse;
4253  }
4254 
4255  if (value == QString::fromLatin1("qualified")) {
4256  objectName = m_namePool->allocateQName(m_targetNamespace, attributeName);
4257  } else {
4258  objectName = m_namePool->allocateQName(QString(), attributeName);
4259  }
4260  } else {
4261  if (m_attributeFormDefault == QString::fromLatin1("qualified")) {
4262  objectName = m_namePool->allocateQName(m_targetNamespace, attributeName);
4263  } else {
4264  objectName = m_namePool->allocateQName(QString(), attributeName);
4265  }
4266  }
4267 
4268  if ((objectName.namespaceURI() == StandardNamespaces::xsi) &&
4269  (m_namePool->stringForLocalName(objectName.localName()) != QString::fromLatin1("type")) &&
4270  (m_namePool->stringForLocalName(objectName.localName()) != QString::fromLatin1("nil")) &&
4271  (m_namePool->stringForLocalName(objectName.localName()) != QString::fromLatin1("schemaLocation")) &&
4272  (m_namePool->stringForLocalName(objectName.localName()) != QString::fromLatin1("noNamespaceSchemaLocation"))) {
4273 
4274  error(QtXmlPatterns::tr("Content of %1 attribute of %2 element must not be from namespace %3.")
4275  .arg(formatAttribute("name"))
4276  .arg(formatElement("attribute"))
4278  return attributeUse;
4279  }
4280  if (m_namePool->stringForLocalName(objectName.localName()) == QString::fromLatin1("xmlns")) {
4281  error(QtXmlPatterns::tr("%1 attribute of %2 element must not be %3.")
4282  .arg(formatAttribute("name"))
4283  .arg(formatElement("attribute"))
4284  .arg(formatData("xmlns")));
4285  return attributeUse;
4286  }
4287 
4288  attribute->setName(objectName);
4289  }
4290 
4291  if (hasAttribute(QString::fromLatin1("type"))) {
4292  hasTypeAttribute = true;
4293 
4294  const QString type = readQNameAttribute(QString::fromLatin1("type"), "attribute");
4296  convertName(type, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName
4297  m_schemaResolver->addAttributeType(attribute, typeName, currentSourceLocation()); // add to resolver
4298  hasTypeSpecified = true;
4299  }
4300 
4301  if (attributeUse->valueConstraint()) {
4302  //TODO: check whether assigning the value constraint of the attribute use to the attribute is correct
4303  if (!attribute->valueConstraint())
4305 
4306  attribute->valueConstraint()->setVariety((XsdAttribute::ValueConstraint::Variety)attributeUse->valueConstraint()->variety());
4307  attribute->valueConstraint()->setValue(attributeUse->valueConstraint()->value());
4308  attribute->valueConstraint()->setLexicalForm(attributeUse->valueConstraint()->lexicalForm());
4309  }
4310  }
4311 
4312  validateIdAttribute("attribute");
4313 
4315 
4316  while (!atEnd()) {
4317  readNext();
4318 
4319  if (isEndElement())
4320  break;
4321 
4322  if (isStartElement()) {
4325 
4326  tagValidator.validate(token);
4327 
4328  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
4329  const XsdAnnotation::Ptr annotation = parseAnnotation();
4330  attribute->addAnnotation(annotation);
4331  } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
4332  if (hasTypeAttribute) {
4333  error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
4334  .arg(formatElement("attribute"))
4335  .arg(formatElement("simpleType"))
4336  .arg(formatAttribute("type")));
4337  break;
4338  }
4339  if (hasRefAttribute) {
4340  error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
4341  .arg(formatElement("attribute"))
4342  .arg(formatElement("simpleType"))
4343  .arg(formatAttribute("ref")));
4344  break;
4345  }
4346 
4348  type->setContext(attribute);
4349  attribute->setType(type);
4350  hasTypeSpecified = true;
4351 
4352  // add it to list of anonymous types as well
4353  addAnonymousType(type);
4354  } else {
4355  parseUnknown();
4356  }
4357  }
4358  }
4359 
4360  if (!hasTypeSpecified) {
4361  attribute->setType(BuiltinTypes::xsAnySimpleType); // default value
4362  }
4363 
4364  tagValidator.finalize();
4365 
4366  return attributeUse;
4367 }
4368 
4370 {
4371  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::AttributeGroup, this);
4372 
4374 
4375  const XsdAttributeGroup::Ptr attributeGroup(new XsdAttributeGroup());
4376 
4377  // parse attributes
4378  const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("attributeGroup"));
4379  attributeGroup->setName(objectName);
4380 
4381  validateIdAttribute("attributeGroup");
4382 
4384 
4385  while (!atEnd()) {
4386  readNext();
4387 
4388  if (isEndElement())
4389  break;
4390 
4391  if (isStartElement()) {
4394 
4395  tagValidator.validate(token);
4396 
4397  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
4398  const XsdAnnotation::Ptr annotation = parseAnnotation();
4399  attributeGroup->addAnnotation(annotation);
4400  } else if (isSchemaTag(XsdSchemaToken::Attribute, token, namespaceToken)) {
4401  const XsdAttributeUse::Ptr attributeUse = parseLocalAttribute(attributeGroup);
4402 
4403  if (attributeUse->useType() == XsdAttributeUse::ProhibitedUse) {
4404  warning(QtXmlPatterns::tr("Specifying use='prohibited' inside an attribute group has no effect."));
4405  } else {
4406  attributeGroup->addAttributeUse(attributeUse);
4407  }
4408  } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) {
4409  const XsdAttributeUse::Ptr attributeUse = parseReferredAttributeGroup();
4410  attributeGroup->addAttributeUse(attributeUse);
4411  } else if (isSchemaTag(XsdSchemaToken::AnyAttribute, token, namespaceToken)) {
4412  const XsdWildcard::Ptr wildcard = parseAnyAttribute();
4413  attributeGroup->setWildcard(wildcard);
4414  } else {
4415  parseUnknown();
4416  }
4417  }
4418  }
4419 
4420  tagValidator.finalize();
4421 
4422  return attributeGroup;
4423 }
4424 
4426 {
4427  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::AttributeGroup, this);
4428 
4430 
4431  const XsdAttributeReference::Ptr attributeReference(new XsdAttributeReference());
4432  attributeReference->setType(XsdAttributeReference::AttributeGroup);
4433  attributeReference->setSourceLocation(currentSourceLocation());
4434 
4435  // parse attributes
4436  const QString reference = readQNameAttribute(QString::fromLatin1("ref"), "attributeGroup");
4437  QXmlName referenceName;
4438  convertName(reference, NamespaceSupport::ElementName, referenceName); // translate qualified name into QXmlName
4439  attributeReference->setReferenceName(referenceName);
4440 
4441  validateIdAttribute("attributeGroup");
4442 
4444 
4445  while (!atEnd()) {
4446  readNext();
4447 
4448  if (isEndElement())
4449  break;
4450 
4451  if (isStartElement()) {
4454 
4455  tagValidator.validate(token);
4456 
4457  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
4458  const XsdAnnotation::Ptr annotation = parseAnnotation();
4459  attributeReference->addAnnotation(annotation);
4460  } else {
4461  parseUnknown();
4462  }
4463  }
4464  }
4465 
4466  tagValidator.finalize();
4467 
4468  return attributeReference;
4469 }
4470 
4472 {
4473  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Element, this);
4474 
4476 
4477  const XsdElement::Ptr element(new XsdElement());
4479  element->scope()->setVariety(XsdElement::Scope::Global);
4480 
4481  bool hasTypeAttribute = false;
4482  bool hasTypeSpecified = false;
4483  bool hasSubstitutionGroup = false;
4484 
4485  // parse attributes
4486  const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("element"));
4487  element->setName(objectName);
4488 
4489  if (hasAttribute(QString::fromLatin1("abstract"))) {
4490  const QString abstract = readAttribute(QString::fromLatin1("abstract"));
4491 
4492  const Boolean::Ptr value = Boolean::fromLexical(abstract);
4493  if (value->hasError()) {
4494  attributeContentError("abstract", "element", abstract, BuiltinTypes::xsBoolean);
4495  return element;
4496  }
4497 
4498  element->setIsAbstract(value->as<Boolean>()->value());
4499  } else {
4500  element->setIsAbstract(false); // the default value
4501  }
4502 
4503  if (hasAttribute(QString::fromLatin1("default")) && hasAttribute(QString::fromLatin1("fixed"))) {
4504  error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
4505  .arg(formatElement("element"))
4506  .arg(formatAttribute("default"))
4507  .arg(formatAttribute("fixed")));
4508  return element;
4509  }
4510 
4511  if (hasAttribute(QString::fromLatin1("default"))) {
4512  const QString value = readAttribute(QString::fromLatin1("default"));
4514  element->valueConstraint()->setVariety(XsdElement::ValueConstraint::Default);
4515  element->valueConstraint()->setValue(value);
4516  } else if (hasAttribute(QString::fromLatin1("fixed"))) {
4517  const QString value = readAttribute(QString::fromLatin1("fixed"));
4519  element->valueConstraint()->setVariety(XsdElement::ValueConstraint::Fixed);
4520  element->valueConstraint()->setValue(value);
4521  }
4522 
4525 
4526  if (hasAttribute(QString::fromLatin1("nillable"))) {
4527  const QString nillable = readAttribute(QString::fromLatin1("nillable"));
4528 
4529  const Boolean::Ptr value = Boolean::fromLexical(nillable);
4530  if (value->hasError()) {
4531  attributeContentError("nillable", "element", nillable, BuiltinTypes::xsBoolean);
4532  return element;
4533  }
4534 
4535  element->setIsNillable(value->as<Boolean>()->value());
4536  } else {
4537  element->setIsNillable(false); // the default value
4538  }
4539 
4540  if (hasAttribute(QString::fromLatin1("type"))) {
4541  const QString type = readQNameAttribute(QString::fromLatin1("type"), "element");
4543  convertName(type, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName
4544  m_schemaResolver->addElementType(element, typeName, currentSourceLocation()); // add to resolver
4545 
4546  hasTypeAttribute = true;
4547  hasTypeSpecified = true;
4548  }
4549 
4550  if (hasAttribute(QString::fromLatin1("substitutionGroup"))) {
4551  QList<QXmlName> elementNames;
4552 
4553  const QString value = readAttribute(QString::fromLatin1("substitutionGroup"));
4554  const QStringList substitutionGroups = value.split(QLatin1Char(' '), QString::SkipEmptyParts);
4555  if (substitutionGroups.isEmpty()) {
4556  attributeContentError("substitutionGroup", "element", value, BuiltinTypes::xsQName);
4557  return element;
4558  }
4559 
4560  for (int i = 0; i < substitutionGroups.count(); ++i) {
4561  const QString value = substitutionGroups.at(i).simplified();
4562  if (!XPathHelper::isQName(value)) {
4563  attributeContentError("substitutionGroup", "element", value, BuiltinTypes::xsQName);
4564  return element;
4565  }
4566 
4567  QXmlName elementName;
4568  convertName(value, NamespaceSupport::ElementName, elementName); // translate qualified name into QXmlName
4569  elementNames.append(elementName);
4570  }
4571 
4572  m_schemaResolver->addSubstitutionGroupAffiliation(element, elementNames, currentSourceLocation()); // add to resolver
4573 
4574  hasSubstitutionGroup = true;
4575  }
4576 
4577  validateIdAttribute("element");
4578 
4579  XsdAlternative::List alternatives;
4580 
4582 
4583  while (!atEnd()) {
4584  readNext();
4585 
4586  if (isEndElement())
4587  break;
4588 
4589  if (isStartElement()) {
4592 
4593  tagValidator.validate(token);
4594 
4595  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
4596  const XsdAnnotation::Ptr annotation = parseAnnotation();
4597  element->addAnnotation(annotation);
4598  } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
4599  if (hasTypeAttribute) {
4600  error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
4601  .arg(formatElement("element"))
4602  .arg(formatElement("simpleType"))
4603  .arg(formatAttribute("type")));
4604  return element;
4605  }
4606 
4608  type->setContext(element);
4609  element->setType(type);
4610 
4611  // add it to list of anonymous types as well
4612  addAnonymousType(type);
4613 
4614  hasTypeSpecified = true;
4615  } else if (isSchemaTag(XsdSchemaToken::ComplexType, token, namespaceToken)) {
4616  if (hasTypeAttribute) {
4617  error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
4618  .arg(formatElement("element"))
4619  .arg(formatElement("complexType"))
4620  .arg(formatAttribute("type")));
4621  return element;
4622  }
4623 
4625  type->setContext(element);
4626  element->setType(type);
4627 
4628  // add it to list of anonymous types as well
4629  addAnonymousType(type);
4630 
4631  hasTypeSpecified = true;
4632  } else if (isSchemaTag(XsdSchemaToken::Alternative, token, namespaceToken)) {
4633  const XsdAlternative::Ptr alternative = parseAlternative();
4634  alternatives.append(alternative);
4635  } else if (isSchemaTag(XsdSchemaToken::Unique, token, namespaceToken)) {
4636  const XsdIdentityConstraint::Ptr constraint = parseUnique();
4637  element->addIdentityConstraint(constraint);
4638  } else if (isSchemaTag(XsdSchemaToken::Key, token, namespaceToken)) {
4639  const XsdIdentityConstraint::Ptr constraint = parseKey();
4640  element->addIdentityConstraint(constraint);
4641  } else if (isSchemaTag(XsdSchemaToken::Keyref, token, namespaceToken)) {
4642  const XsdIdentityConstraint::Ptr constraint = parseKeyRef(element);
4643  element->addIdentityConstraint(constraint);
4644  } else {
4645  parseUnknown();
4646  }
4647  }
4648  }
4649 
4650  tagValidator.finalize();
4651 
4652  if (!hasTypeSpecified) {
4653  if (hasSubstitutionGroup)
4655  else
4656  element->setType(BuiltinTypes::xsAnyType);
4657  }
4658 
4659  if (!alternatives.isEmpty()) {
4661 
4662  for (int i = 0; i < alternatives.count(); ++i) {
4663  if (alternatives.at(i)->test())
4664  element->typeTable()->addAlternative(alternatives.at(i));
4665 
4666  if (i == (alternatives.count() - 1)) { // the final one
4667  if (!alternatives.at(i)->test()) {
4668  element->typeTable()->setDefaultTypeDefinition(alternatives.at(i));
4669  } else {
4670  const XsdAlternative::Ptr alternative(new XsdAlternative());
4671  if (element->type())
4672  alternative->setType(element->type());
4673  else
4674  m_schemaResolver->addAlternativeType(alternative, element); // add to resolver
4675 
4676  element->typeTable()->setDefaultTypeDefinition(alternative);
4677  }
4678  }
4679  }
4680  }
4681 
4682  return element;
4683 }
4684 
4686 {
4687  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Element, this);
4688 
4690 
4691  bool hasRefAttribute = false;
4692  bool hasTypeAttribute = false;
4693  bool hasTypeSpecified = false;
4694 
4695  XsdTerm::Ptr term;
4696  XsdElement::Ptr element;
4697  if (hasAttribute(QString::fromLatin1("ref"))) {
4698  term = XsdReference::Ptr(new XsdReference());
4699  hasRefAttribute = true;
4700  } else {
4701  term = XsdElement::Ptr(new XsdElement());
4702  element = term;
4703  }
4704 
4705  if (hasRefAttribute) {
4706  if (hasAttribute(QString::fromLatin1("name"))) {
4707  error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
4708  .arg(formatElement("element"))
4709  .arg(formatAttribute("ref"))
4710  .arg(formatAttribute("name")));
4711  return term;
4712  } else if (hasAttribute(QString::fromLatin1("block"))) {
4713  error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
4714  .arg(formatElement("element"))
4715  .arg(formatAttribute("ref"))
4716  .arg(formatAttribute("block")));
4717  return term;
4718  } else if (hasAttribute(QString::fromLatin1("nillable"))) {
4719  error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
4720  .arg(formatElement("element"))
4721  .arg(formatAttribute("ref"))
4722  .arg(formatAttribute("nillable")));
4723  return term;
4724  } else if (hasAttribute(QString::fromLatin1("default"))) {
4725  error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
4726  .arg(formatElement("element"))
4727  .arg(formatAttribute("ref"))
4728  .arg(formatAttribute("default")));
4729  return term;
4730  } else if (hasAttribute(QString::fromLatin1("fixed"))) {
4731  error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
4732  .arg(formatElement("element"))
4733  .arg(formatAttribute("ref"))
4734  .arg(formatAttribute("fixed")));
4735  return term;
4736  } else if (hasAttribute(QString::fromLatin1("form"))) {
4737  error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
4738  .arg(formatElement("element"))
4739  .arg(formatAttribute("ref"))
4740  .arg(formatAttribute("form")));
4741  return term;
4742  } else if (hasAttribute(QString::fromLatin1("type"))) {
4743  error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
4744  .arg(formatElement("element"))
4745  .arg(formatAttribute("ref"))
4746  .arg(formatAttribute("type")));
4747  return term;
4748  }
4749  }
4750 
4751  // parse attributes
4752  if (!parseMinMaxConstraint(particle, "element")) {
4753  return element;
4754  }
4755 
4757  error(QtXmlPatterns::tr("%1 element must have either %2 or %3 attribute.")
4758  .arg(formatElement("element"))
4759  .arg(formatAttribute("name"))
4760  .arg(formatAttribute("ref")));
4761  return element;
4762  }
4763 
4764  if (hasRefAttribute) {
4765  const QString ref = readQNameAttribute(QString::fromLatin1("ref"), "element");
4766  QXmlName referenceName;
4767  convertName(ref, NamespaceSupport::ElementName, referenceName); // translate qualified name into QXmlName
4768 
4769  const XsdReference::Ptr reference = term;
4770  reference->setReferenceName(referenceName);
4771  reference->setType(XsdReference::Element);
4772  reference->setSourceLocation(currentSourceLocation());
4773  } else {
4775  element->scope()->setVariety(XsdElement::Scope::Local);
4776  element->scope()->setParent(parent);
4777 
4778  if (hasAttribute(QString::fromLatin1("name"))) {
4779  const QString elementName = readNameAttribute("element");
4780 
4781  QXmlName objectName;
4782  if (hasAttribute(QString::fromLatin1("form"))) {
4783  const QString value = readAttribute(QString::fromLatin1("form"));
4784  if (value != QString::fromLatin1("qualified") && value != QString::fromLatin1("unqualified")) {
4785  attributeContentError("form", "element", value);
4786  return element;
4787  }
4788 
4789  if (value == QString::fromLatin1("qualified")) {
4790  objectName = m_namePool->allocateQName(m_targetNamespace, elementName);
4791  } else {
4792  objectName = m_namePool->allocateQName(QString(), elementName);
4793  }
4794  } else {
4795  if (m_elementFormDefault == QString::fromLatin1("qualified")) {
4796  objectName = m_namePool->allocateQName(m_targetNamespace, elementName);
4797  } else {
4798  objectName = m_namePool->allocateQName(QString(), elementName);
4799  }
4800  }
4801 
4802  element->setName(objectName);
4803  }
4804 
4805  if (hasAttribute(QString::fromLatin1("nillable"))) {
4806  const QString nillable = readAttribute(QString::fromLatin1("nillable"));
4807 
4808  const Boolean::Ptr value = Boolean::fromLexical(nillable);
4809  if (value->hasError()) {
4810  attributeContentError("nillable", "element", nillable, BuiltinTypes::xsBoolean);
4811  return term;
4812  }
4813 
4814  element->setIsNillable(value->as<Boolean>()->value());
4815  } else {
4816  element->setIsNillable(false); // the default value
4817  }
4818 
4819  if (hasAttribute(QString::fromLatin1("default")) && hasAttribute(QString::fromLatin1("fixed"))) {
4820  error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
4821  .arg(formatElement("element"))
4822  .arg(formatAttribute("default"))
4823  .arg(formatAttribute("fixed")));
4824  return element;
4825  }
4826 
4827  if (hasAttribute(QString::fromLatin1("default"))) {
4828  const QString value = readAttribute(QString::fromLatin1("default"));
4830  element->valueConstraint()->setVariety(XsdElement::ValueConstraint::Default);
4831  element->valueConstraint()->setValue(value);
4832  } else if (hasAttribute(QString::fromLatin1("fixed"))) {
4833  const QString value = readAttribute(QString::fromLatin1("fixed"));
4835  element->valueConstraint()->setVariety(XsdElement::ValueConstraint::Fixed);
4836  element->valueConstraint()->setValue(value);
4837  }
4838 
4839  if (hasAttribute(QString::fromLatin1("type"))) {
4840  const QString type = readQNameAttribute(QString::fromLatin1("type"), "element");
4842  convertName(type, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName
4843  m_schemaResolver->addElementType(element, typeName, currentSourceLocation()); // add to resolver
4844 
4845  hasTypeAttribute = true;
4846  hasTypeSpecified = true;
4847  }
4848 
4850  }
4851 
4852  validateIdAttribute("element");
4853 
4854  XsdAlternative::List alternatives;
4855 
4857 
4858  while (!atEnd()) {
4859  readNext();
4860 
4861  if (isEndElement())
4862  break;
4863 
4864  if (isStartElement()) {
4867 
4868  tagValidator.validate(token);
4869 
4870  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
4871  const XsdAnnotation::Ptr annotation = parseAnnotation();
4872  term->addAnnotation(annotation);
4873  } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
4874  if (hasRefAttribute) {
4875  error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
4876  .arg(formatElement("element"))
4877  .arg(formatElement("simpleType"))
4878  .arg(formatAttribute("ref")));
4879  return term;
4880  } else if (hasTypeAttribute) {
4881  error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
4882  .arg(formatElement("element"))
4883  .arg(formatElement("simpleType"))
4884  .arg(formatAttribute("type")));
4885  return term;
4886  }
4887 
4889  type->setContext(element);
4890  element->setType(type);
4891 
4892  // add it to list of anonymous types as well
4893  addAnonymousType(type);
4894 
4895  hasTypeSpecified = true;
4896  } else if (isSchemaTag(XsdSchemaToken::ComplexType, token, namespaceToken)) {
4897  if (hasRefAttribute) {
4898  error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
4899  .arg(formatElement("element"))
4900  .arg(formatElement("complexType"))
4901  .arg(formatAttribute("ref")));
4902  return term;
4903  } else if (hasTypeAttribute) {
4904  error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
4905  .arg(formatElement("element"))
4906  .arg(formatElement("complexType"))
4907  .arg(formatAttribute("type")));
4908  return term;
4909  }
4910 
4912  type->setContext(element);
4913  element->setType(type);
4914 
4915  // add it to list of anonymous types as well
4916  addAnonymousType(type);
4917 
4918  hasTypeSpecified = true;
4919  } else if (isSchemaTag(XsdSchemaToken::Alternative, token, namespaceToken)) {
4920  if (hasRefAttribute) {
4921  error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
4922  .arg(formatElement("element"))
4923  .arg(formatElement("alternative"))
4924  .arg(formatAttribute("ref")));
4925  return term;
4926  }
4927 
4928  const XsdAlternative::Ptr alternative = parseAlternative();
4929  alternatives.append(alternative);
4930  } else if (isSchemaTag(XsdSchemaToken::Unique, token, namespaceToken)) {
4931  if (hasRefAttribute) {
4932  error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
4933  .arg(formatElement("element"))
4934  .arg(formatElement("unique"))
4935  .arg(formatAttribute("ref")));
4936  return term;
4937  }
4938 
4939  const XsdIdentityConstraint::Ptr constraint = parseUnique();
4940  element->addIdentityConstraint(constraint);
4941  } else if (isSchemaTag(XsdSchemaToken::Key, token, namespaceToken)) {
4942  if (hasRefAttribute) {
4943  error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
4944  .arg(formatElement("element"))
4945  .arg(formatElement("key"))
4946  .arg(formatAttribute("ref")));
4947  return term;
4948  }
4949 
4950  const XsdIdentityConstraint::Ptr constraint = parseKey();
4951  element->addIdentityConstraint(constraint);
4952  } else if (isSchemaTag(XsdSchemaToken::Keyref, token, namespaceToken)) {
4953  if (hasRefAttribute) {
4954  error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
4955  .arg(formatElement("element"))
4956  .arg(formatElement("keyref"))
4957  .arg(formatAttribute("ref")));
4958  return term;
4959  }
4960 
4961  const XsdIdentityConstraint::Ptr constraint = parseKeyRef(element);
4962  element->addIdentityConstraint(constraint);
4963  } else {
4964  parseUnknown();
4965  }
4966  }
4967  }
4968 
4969  tagValidator.finalize();
4970 
4971  if (!hasTypeSpecified && !hasRefAttribute)
4972  element->setType(BuiltinTypes::xsAnyType);
4973 
4974  if (!hasRefAttribute && !alternatives.isEmpty()) {
4976 
4977  for (int i = 0; i < alternatives.count(); ++i) {
4978  if (alternatives.at(i)->test())
4979  element->typeTable()->addAlternative(alternatives.at(i));
4980 
4981  if (i == (alternatives.count() - 1)) { // the final one
4982  if (!alternatives.at(i)->test()) {
4983  element->typeTable()->setDefaultTypeDefinition(alternatives.at(i));
4984  } else {
4985  const XsdAlternative::Ptr alternative(new XsdAlternative());
4986  if (element->type())
4987  alternative->setType(element->type());
4988  else
4989  m_schemaResolver->addAlternativeType(alternative, element); // add to resolver
4990 
4991  element->typeTable()->setDefaultTypeDefinition(alternative);
4992  }
4993  }
4994  }
4995  }
4996 
4997  return term;
4998 }
4999 
5001 {
5002  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Unique, this);
5003 
5005 
5006  const XsdIdentityConstraint::Ptr constraint(new XsdIdentityConstraint());
5008 
5009  // parse attributes
5010  const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("unique"));
5011  constraint->setName(objectName);
5012 
5013  validateIdAttribute("unique");
5014 
5016 
5017  while (!atEnd()) {
5018  readNext();
5019 
5020  if (isEndElement())
5021  break;
5022 
5023  if (isStartElement()) {
5026 
5027  tagValidator.validate(token);
5028 
5029  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
5030  const XsdAnnotation::Ptr annotation = parseAnnotation();
5031  constraint->addAnnotation(annotation);
5032  } else if (isSchemaTag(XsdSchemaToken::Selector, token, namespaceToken)) {
5033  parseSelector(constraint);
5034  } else if (isSchemaTag(XsdSchemaToken::Field, token, namespaceToken)) {
5035  parseField(constraint);
5036  } else {
5037  parseUnknown();
5038  }
5039  }
5040  }
5041 
5042  // add constraint to schema for further checking
5043  addIdentityConstraint(constraint);
5044 
5045  tagValidator.finalize();
5046 
5047  return constraint;
5048 }
5049 
5051 {
5052  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Key, this);
5053 
5055 
5056  const XsdIdentityConstraint::Ptr constraint(new XsdIdentityConstraint());
5058 
5059  // parse attributes
5061  constraint->setName(objectName);
5062 
5063  validateIdAttribute("key");
5064 
5066 
5067  while (!atEnd()) {
5068  readNext();
5069 
5070  if (isEndElement())
5071  break;
5072 
5073  if (isStartElement()) {
5076 
5077  tagValidator.validate(token);
5078 
5079  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
5080  const XsdAnnotation::Ptr annotation = parseAnnotation();
5081  constraint->addAnnotation(annotation);
5082  } else if (isSchemaTag(XsdSchemaToken::Selector, token, namespaceToken)) {
5083  parseSelector(constraint);
5084  } else if (isSchemaTag(XsdSchemaToken::Field, token, namespaceToken)) {
5085  parseField(constraint);
5086  } else {
5087  parseUnknown();
5088  }
5089  }
5090  }
5091 
5092  // add constraint to schema for further checking
5093  addIdentityConstraint(constraint);
5094 
5095  tagValidator.finalize();
5096 
5097  return constraint;
5098 }
5099 
5101 {
5102  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Keyref, this);
5103 
5105 
5106  const XsdIdentityConstraint::Ptr constraint(new XsdIdentityConstraint());
5108 
5109  // parse attributes
5110  const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("keyref"));
5111  constraint->setName(objectName);
5112 
5113  const QString refer = readQNameAttribute(QString::fromLatin1("refer"), "keyref");
5114  QXmlName referenceName;
5115  convertName(refer, NamespaceSupport::ElementName, referenceName); // translate qualified name into QXmlName
5116  m_schemaResolver->addKeyReference(element, constraint, referenceName, currentSourceLocation()); // add to resolver
5117 
5118  validateIdAttribute("keyref");
5119 
5121 
5122  while (!atEnd()) {
5123  readNext();
5124 
5125  if (isEndElement())
5126  break;
5127 
5128  if (isStartElement()) {
5131 
5132  tagValidator.validate(token);
5133 
5134  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
5135  const XsdAnnotation::Ptr annotation = parseAnnotation();
5136  constraint->addAnnotation(annotation);
5137  } else if (isSchemaTag(XsdSchemaToken::Selector, token, namespaceToken)) {
5138  parseSelector(constraint);
5139  } else if (isSchemaTag(XsdSchemaToken::Field, token, namespaceToken)) {
5140  parseField(constraint);
5141  } else {
5142  parseUnknown();
5143  }
5144  }
5145  }
5146 
5147  // add constraint to schema for further checking
5148  addIdentityConstraint(constraint);
5149 
5150  tagValidator.finalize();
5151 
5152  return constraint;
5153 }
5154 
5156 {
5157  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Selector, this);
5158 
5160 
5161  // parse attributes
5162  const XsdXPathExpression::Ptr expression = readXPathExpression("selector");
5163 
5164  const QString xpath = readXPathAttribute(QString::fromLatin1("xpath"), XPathSelector, "selector");
5165  expression->setExpression(xpath);
5166 
5167  ptr->setSelector(expression);
5168 
5169  validateIdAttribute("selector");
5170 
5172 
5173  while (!atEnd()) {
5174  readNext();
5175 
5176  if (isEndElement())
5177  break;
5178 
5179  if (isStartElement()) {
5182 
5183  tagValidator.validate(token);
5184 
5185  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
5186  const XsdAnnotation::Ptr annotation = parseAnnotation();
5187  expression->addAnnotation(annotation);
5188  } else {
5189  parseUnknown();
5190  }
5191  }
5192  }
5193 
5194  tagValidator.finalize();
5195 }
5196 
5198 {
5199  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Field, this);
5200 
5202 
5203  // parse attributes
5204  const XsdXPathExpression::Ptr expression = readXPathExpression("field");
5205 
5206  const QString xpath = readXPathAttribute(QString::fromLatin1("xpath"), XPathField, "field");
5207  expression->setExpression(xpath);
5208 
5209  ptr->addField(expression);
5210 
5211  validateIdAttribute("field");
5212 
5214 
5215  while (!atEnd()) {
5216  readNext();
5217 
5218  if (isEndElement())
5219  break;
5220 
5221  if (isStartElement()) {
5224 
5225  tagValidator.validate(token);
5226 
5227  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
5228  const XsdAnnotation::Ptr annotation = parseAnnotation();
5229  expression->addAnnotation(annotation);
5230  } else {
5231  parseUnknown();
5232  }
5233  }
5234  }
5235 
5236  tagValidator.finalize();
5237 }
5238 
5240 {
5241  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Alternative, this);
5242 
5244 
5245  const XsdAlternative::Ptr alternative(new XsdAlternative());
5246 
5247  bool hasTypeSpecified = false;
5248 
5249  if (hasAttribute(QString::fromLatin1("test"))) {
5250  const XsdXPathExpression::Ptr expression = readXPathExpression("alternative");
5251 
5252  const QString test = readXPathAttribute(QString::fromLatin1("test"), XPath20, "alternative");
5253  expression->setExpression(test);
5254 
5255  alternative->setTest(expression);
5256  }
5257 
5258  if (hasAttribute(QString::fromLatin1("type"))) {
5259  const QString type = readQNameAttribute(QString::fromLatin1("type"), "alternative");
5261  convertName(type, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName
5262  m_schemaResolver->addAlternativeType(alternative, typeName, currentSourceLocation()); // add to resolver
5263 
5264  hasTypeSpecified = true;
5265  }
5266 
5267  validateIdAttribute("alternative");
5268 
5270 
5271  while (!atEnd()) {
5272  readNext();
5273 
5274  if (isEndElement())
5275  break;
5276 
5277  if (isStartElement()) {
5280 
5281  tagValidator.validate(token);
5282 
5283  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
5284  const XsdAnnotation::Ptr annotation = parseAnnotation();
5285  alternative->addAnnotation(annotation);
5286  } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
5288  alternative->setType(type);
5289 
5290  // add it to list of anonymous types as well
5291  addAnonymousType(type);
5292 
5293  hasTypeSpecified = true;
5294  } else if (isSchemaTag(XsdSchemaToken::ComplexType, token, namespaceToken)) {
5296  alternative->setType(type);
5297 
5298  // add it to list of anonymous types as well
5299  addAnonymousType(type);
5300 
5301  hasTypeSpecified = true;
5302  } else {
5303  parseUnknown();
5304  }
5305  }
5306  }
5307 
5308  tagValidator.finalize();
5309 
5310  if (!hasTypeSpecified) {
5311  error(QtXmlPatterns::tr("%1 element must have either %2 attribute or %3 or %4 as child element.")
5312  .arg(formatElement("alternative"))
5313  .arg(formatAttribute("type"))
5314  .arg(formatElement("simpleType"))
5315  .arg(formatElement("complexType")));
5316  return alternative;
5317  }
5318 
5319  return alternative;
5320 }
5321 
5323 {
5324  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Notation, this);
5325 
5327 
5328  const XsdNotation::Ptr notation(new XsdNotation());
5329 
5330  // parse attributes
5331  const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("notation"));
5332  notation->setName(objectName);
5333 
5334  bool hasOptionalAttribute = false;
5335 
5336  if (hasAttribute(QString::fromLatin1("public"))) {
5337  const QString value = readAttribute(QString::fromLatin1("public"));
5338  if (!value.isEmpty()) {
5340  if (publicId->hasError()) {
5341  attributeContentError("public", "notation", value, BuiltinTypes::xsToken);
5342  return notation;
5343  }
5344  notation->setPublicId(publicId);
5345  }
5346 
5347  hasOptionalAttribute = true;
5348  }
5349 
5350  if (hasAttribute(QString::fromLatin1("system"))) {
5351  const QString value = readAttribute(QString::fromLatin1("system"));
5352  if (!isValidUri(value)) {
5353  attributeContentError("system", "notation", value, BuiltinTypes::xsAnyURI);
5354  return notation;
5355  }
5356 
5357  if (!value.isEmpty()) {
5358  const AnyURI::Ptr systemId = AnyURI::fromLexical(value);
5359  notation->setSystemId(systemId);
5360  }
5361 
5362  hasOptionalAttribute = true;
5363  }
5364 
5365  if (!hasOptionalAttribute) {
5366  error(QtXmlPatterns::tr("%1 element requires either %2 or %3 attribute.")
5367  .arg(formatElement("notation"))
5368  .arg(formatAttribute("public"))
5369  .arg(formatAttribute("system")));
5370  return notation;
5371  }
5372 
5373  validateIdAttribute("notation");
5374 
5376 
5377  while (!atEnd()) {
5378  readNext();
5379 
5380  if (isEndElement())
5381  break;
5382 
5383  if (isCharacters() || isEntityReference()) {
5384  if (!text().toString().trimmed().isEmpty()) {
5385  error(QtXmlPatterns::tr("Text or entity references not allowed inside %1 element").arg(formatElement("notation.")));
5386  return notation;
5387  }
5388  }
5389 
5390  if (isStartElement()) {
5393 
5394  tagValidator.validate(token);
5395 
5396  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
5397  const XsdAnnotation::Ptr annotation = parseAnnotation();
5398  notation->addAnnotation(annotation);
5399  } else {
5400  parseUnknown();
5401  }
5402  }
5403  }
5404 
5405  tagValidator.finalize();
5406 
5407  return notation;
5408 }
5409 
5411 {
5412  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Any, this);
5413 
5415 
5416  const XsdWildcard::Ptr wildcard(new XsdWildcard());
5417 
5418  // parse attributes
5419  if (!parseMinMaxConstraint(particle, "any")) {
5420  return wildcard;
5421  }
5422 
5423  if (hasAttribute(QString::fromLatin1("namespace"))) {
5425  if ((values.contains(QString::fromLatin1("##any")) || values.contains(QString::fromLatin1("##other"))) && values.count() != 1) {
5426  error(QtXmlPatterns::tr("%1 attribute of %2 element must contain %3, %4 or a list of URIs.")
5427  .arg(formatAttribute("namespace"))
5428  .arg(formatElement("any"))
5429  .arg(formatData("##any"))
5430  .arg(formatData("##other")));
5431  return wildcard;
5432  }
5433 
5434  if (values.contains(QString::fromLatin1("##any"))) {
5436  } else if (values.contains(QString::fromLatin1("##other"))) {
5438  if (!m_targetNamespace.isEmpty())
5439  wildcard->namespaceConstraint()->setNamespaces(QSet<QString>() << m_targetNamespace);
5440  else
5441  wildcard->namespaceConstraint()->setNamespaces(QSet<QString>() << XsdWildcard::absentNamespace());
5442  } else {
5444  QStringList newValues = values.toList();
5445 
5446  // replace the ##targetNamespace entry
5447  for (int i = 0; i < newValues.count(); ++i) {
5448  if (newValues.at(i) == QString::fromLatin1("##targetNamespace")) {
5449  if (!m_targetNamespace.isEmpty())
5450  newValues[i] = m_targetNamespace;
5451  else
5452  newValues[i] = XsdWildcard::absentNamespace();
5453  } else if (newValues.at(i) == QString::fromLatin1("##local")) {
5454  newValues[i] = XsdWildcard::absentNamespace();
5455  }
5456  }
5457 
5458  // check for invalid URIs
5459  for (int i = 0; i < newValues.count(); ++i) {
5460  const QString stringValue = newValues.at(i);
5461  if (stringValue == XsdWildcard::absentNamespace())
5462  continue;
5463 
5464  if (!isValidUri(stringValue)) {
5465  attributeContentError("namespace", "any", stringValue, BuiltinTypes::xsAnyURI);
5466  return wildcard;
5467  }
5468  }
5469 
5470  wildcard->namespaceConstraint()->setNamespaces(newValues.toSet());
5471  }
5472  } else {
5474  }
5475 
5476  if (hasAttribute(QString::fromLatin1("processContents"))) {
5477  const QString value = readAttribute(QString::fromLatin1("processContents"));
5478  if (value != QString::fromLatin1("lax") &&
5479  value != QString::fromLatin1("skip") &&
5480  value != QString::fromLatin1("strict")) {
5481  attributeContentError("processContents", "any", value);
5482  return wildcard;
5483  }
5484 
5485  if (value == QString::fromLatin1("lax")) {
5487  } else if (value == QString::fromLatin1("skip")) {
5489  } else if (value == QString::fromLatin1("strict")) {
5491  }
5492  } else {
5494  }
5495 
5496  validateIdAttribute("any");
5497 
5499 
5500  while (!atEnd()) {
5501  readNext();
5502 
5503  if (isEndElement())
5504  break;
5505 
5506  if (isStartElement()) {
5509 
5510  tagValidator.validate(token);
5511 
5512  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
5513  const XsdAnnotation::Ptr annotation = parseAnnotation();
5514  wildcard->addAnnotation(annotation);
5515  } else {
5516  parseUnknown();
5517  }
5518  }
5519  }
5520 
5521  tagValidator.finalize();
5522 
5523  return wildcard;
5524 }
5525 
5527 {
5528  const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::AnyAttribute, this);
5529 
5531 
5532  const XsdWildcard::Ptr wildcard(new XsdWildcard());
5533 
5534  // parse attributes
5535  if (hasAttribute(QString::fromLatin1("namespace"))) {
5537  if ((values.contains(QString::fromLatin1("##any")) || values.contains(QString::fromLatin1("##other"))) && values.count() != 1) {
5538  error(QtXmlPatterns::tr("%1 attribute of %2 element must contain %3, %4 or a list of URIs.")
5539  .arg(formatAttribute("namespace"))
5540  .arg(formatElement("anyAttribute"))
5541  .arg(formatData("##any"))
5542  .arg(formatData("##other")));
5543  return wildcard;
5544  }
5545 
5546  if (values.contains(QString::fromLatin1("##any"))) {
5548  } else if (values.contains(QString::fromLatin1("##other"))) {
5550  if (!m_targetNamespace.isEmpty())
5551  wildcard->namespaceConstraint()->setNamespaces(QSet<QString>() << m_targetNamespace);
5552  else
5553  wildcard->namespaceConstraint()->setNamespaces(QSet<QString>() << XsdWildcard::absentNamespace());
5554  } else {
5556  QStringList newValues = values.toList();
5557 
5558  // replace the ##targetNamespace entry
5559  for (int i = 0; i < newValues.count(); ++i) {
5560  if (newValues.at(i) == QString::fromLatin1("##targetNamespace")) {
5561  if (!m_targetNamespace.isEmpty())
5562  newValues[i] = m_targetNamespace;
5563  else
5564  newValues[i] = XsdWildcard::absentNamespace();
5565  } else if (newValues.at(i) == QString::fromLatin1("##local")) {
5566  newValues[i] = XsdWildcard::absentNamespace();
5567  }
5568  }
5569 
5570  // check for invalid URIs
5571  for (int i = 0; i < newValues.count(); ++i) {
5572  const QString stringValue = newValues.at(i);
5573  if (stringValue == XsdWildcard::absentNamespace())
5574  continue;
5575 
5576  if (!isValidUri(stringValue)) {
5577  attributeContentError("namespace", "anyAttribute", stringValue, BuiltinTypes::xsAnyURI);
5578  return wildcard;
5579  }
5580  }
5581 
5582  wildcard->namespaceConstraint()->setNamespaces(newValues.toSet());
5583  }
5584  } else {
5586  }
5587 
5588  if (hasAttribute(QString::fromLatin1("processContents"))) {
5589  const QString value = readAttribute(QString::fromLatin1("processContents"));
5590  if (value != QString::fromLatin1("lax") &&
5591  value != QString::fromLatin1("skip") &&
5592  value != QString::fromLatin1("strict")) {
5593  attributeContentError("processContents", "anyAttribute", value);
5594  return wildcard;
5595  }
5596 
5597  if (value == QString::fromLatin1("lax")) {
5599  } else if (value == QString::fromLatin1("skip")) {
5601  } else if (value == QString::fromLatin1("strict")) {
5603  }
5604  } else {
5606  }
5607 
5608  validateIdAttribute("anyAttribute");
5609 
5611 
5612  while (!atEnd()) {
5613  readNext();
5614 
5615  if (isEndElement())
5616  break;
5617 
5618  if (isStartElement()) {
5621 
5622  tagValidator.validate(token);
5623 
5624  if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
5625  const XsdAnnotation::Ptr annotation = parseAnnotation();
5626  wildcard->addAnnotation(annotation);
5627  } else {
5628  parseUnknown();
5629  }
5630  }
5631  }
5632 
5633  tagValidator.finalize();
5634 
5635  return wildcard;
5636 }
5637 
5638 
5640 {
5644 
5645  while (!atEnd()) {
5646  readNext();
5647 
5648  if (isEndElement())
5649  break;
5650 
5651  if (isStartElement())
5653  }
5654 
5656 }
5657 
5659 {
5663 
5664  error(QtXmlPatterns::tr("%1 element is not allowed in this context.").arg(formatElement(name().toString())));
5665 
5666  while (!atEnd()) {
5667  readNext();
5668 
5669  if (isEndElement())
5670  break;
5671 
5672  if (isStartElement())
5673  parseUnknown();
5674  }
5675 
5677 }
5678 
5679 bool XsdSchemaParser::parseMinMaxConstraint(const XsdParticle::Ptr &particle, const char *elementName)
5680 {
5681  if (hasAttribute(QString::fromLatin1("minOccurs"))) {
5682  const QString value = readAttribute(QString::fromLatin1("minOccurs"));
5683 
5685  if (integer->hasError()) {
5686  attributeContentError("minOccurs", elementName, value, BuiltinTypes::xsNonNegativeInteger);
5687  return false;
5688  } else {
5690  }
5691  } else {
5692  particle->setMinimumOccurs(1);
5693  }
5694 
5695  if (hasAttribute(QString::fromLatin1("maxOccurs"))) {
5696  const QString value = readAttribute(QString::fromLatin1("maxOccurs"));
5697 
5698  if (value == QString::fromLatin1("unbounded")) {
5699  particle->setMaximumOccursUnbounded(true);
5700  } else {
5701  particle->setMaximumOccursUnbounded(false);
5703  if (integer->hasError()) {
5704  attributeContentError("maxOccurs", elementName, value, BuiltinTypes::xsNonNegativeInteger);
5705  return false;
5706  } else {
5708  }
5709  }
5710  } else {
5711  particle->setMaximumOccursUnbounded(false);
5712  particle->setMaximumOccurs(1);
5713  }
5714 
5715  if (!particle->maximumOccursUnbounded()) {
5716  if (particle->maximumOccurs() < particle->minimumOccurs()) {
5717  error(QtXmlPatterns::tr("%1 attribute of %2 element has larger value than %3 attribute.")
5718  .arg(formatAttribute("minOccurs"))
5719  .arg(formatElement(elementName))
5720  .arg(formatAttribute("maxOccurs")));
5721  return false;
5722  }
5723  }
5724 
5725  return true;
5726 }
5727 
5729 {
5731  location.setLine(lineNumber());
5732  location.setColumn(columnNumber());
5733  location.setUri(m_documentURI);
5734 
5735  return location;
5736 }
5737 
5739 {
5740  bool result = m_namespaceSupport.processName(qualifiedName, type, name);
5741  if (!result) {
5742  error(QtXmlPatterns::tr("Prefix of qualified name %1 is not defined.").arg(formatKeyword(qualifiedName)));
5743  }
5744 }
5745 
5747 {
5748  const QString value = readAttribute(QString::fromLatin1("name")).simplified();
5749  if (!QXmlUtils::isNCName(value)) {
5750  attributeContentError("name", elementName, value, BuiltinTypes::xsNCName);
5751  return QString();
5752  } else {
5753  return value;
5754  }
5755 }
5756 
5757 QString XsdSchemaParser::readQNameAttribute(const QString &typeAttribute, const char *elementName)
5758 {
5759  const QString value = readAttribute(typeAttribute).simplified();
5760  if (!XPathHelper::isQName(value)) {
5761  attributeContentError(typeAttribute.toLatin1(), elementName, value, BuiltinTypes::xsQName);
5762  return QString();
5763  } else {
5764  return value;
5765  }
5766 }
5767 
5768 QString XsdSchemaParser::readNamespaceAttribute(const QString &attributeName, const char *elementName)
5769 {
5770  const QString value = readAttribute(attributeName);
5771  if (value.isEmpty()) {
5772  attributeContentError(attributeName.toLatin1(), elementName, value, BuiltinTypes::xsAnyURI);
5773  return QString();
5774  }
5775 
5776  return value;
5777 }
5778 
5779 SchemaType::DerivationConstraints XsdSchemaParser::readDerivationConstraintAttribute(const SchemaType::DerivationConstraints &allowedConstraints, const char *elementName)
5780 {
5781  // first convert the flags into strings for easier comparison
5782  QSet<QString> allowedContent;
5783  if (allowedConstraints & SchemaType::RestrictionConstraint)
5784  allowedContent.insert(QString::fromLatin1("restriction"));
5785  if (allowedConstraints & SchemaType::ExtensionConstraint)
5786  allowedContent.insert(QString::fromLatin1("extension"));
5787  if (allowedConstraints & SchemaType::ListConstraint)
5788  allowedContent.insert(QString::fromLatin1("list"));
5789  if (allowedConstraints & SchemaType::UnionConstraint)
5790  allowedContent.insert(QString::fromLatin1("union"));
5791 
5792  // read content from the attribute if available, otherwise use the default definitions from the schema tag
5793  QString content;
5794  if (hasAttribute(QString::fromLatin1("final"))) {
5795  content = readAttribute(QString::fromLatin1("final"));
5796 
5797  // split string into list to validate the content of the attribute
5799  for (int i = 0; i < values.count(); i++) {
5800  const QString value = values.at(i);
5801  if (!allowedContent.contains(value) && (value != QString::fromLatin1("#all"))) {
5802  attributeContentError("final", elementName, value);
5803  return SchemaType::DerivationConstraints();
5804  }
5805 
5806  if ((value == QString::fromLatin1("#all")) && values.count() != 1) {
5807  error(QtXmlPatterns::tr("%1 attribute of %2 element must either contain %3 or the other values.")
5808  .arg(formatAttribute("final"))
5809  .arg(formatElement(elementName))
5810  .arg(formatData("#all")));
5811  return SchemaType::DerivationConstraints();
5812  }
5813  }
5814  } else {
5815  // content of the default value has been validated in parseSchema already
5816  content = m_finalDefault;
5817  }
5818 
5819  QSet<QString> contentSet = content.split(QLatin1Char(' '), QString::SkipEmptyParts).toSet();
5820 
5821  // if the '#all' tag is defined, we return all allowed values
5822  if (contentSet.contains(QString::fromLatin1("#all"))) {
5823  return allowedConstraints;
5824  } else { // return the values from content set that intersects with the allowed values
5825  contentSet.intersect(allowedContent);
5826 
5827  SchemaType::DerivationConstraints constraints;
5828 
5829  if (contentSet.contains(QString::fromLatin1("restriction")))
5830  constraints |= SchemaType::RestrictionConstraint;
5831  if (contentSet.contains(QString::fromLatin1("extension")))
5832  constraints |= SchemaType::ExtensionConstraint;
5833  if (contentSet.contains(QString::fromLatin1("list")))
5834  constraints |= SchemaType::ListConstraint;
5835  if (contentSet.contains(QString::fromLatin1("union")))
5836  constraints |= SchemaType::UnionConstraint;
5837 
5838  return constraints;
5839  }
5840 }
5841 
5842 NamedSchemaComponent::BlockingConstraints XsdSchemaParser::readBlockingConstraintAttribute(const NamedSchemaComponent::BlockingConstraints &allowedConstraints, const char *elementName)
5843 {
5844  // first convert the flags into strings for easier comparison
5845  QSet<QString> allowedContent;
5846  if (allowedConstraints & NamedSchemaComponent::RestrictionConstraint)
5847  allowedContent.insert(QString::fromLatin1("restriction"));
5848  if (allowedConstraints & NamedSchemaComponent::ExtensionConstraint)
5849  allowedContent.insert(QString::fromLatin1("extension"));
5850  if (allowedConstraints & NamedSchemaComponent::SubstitutionConstraint)
5851  allowedContent.insert(QString::fromLatin1("substitution"));
5852 
5853  // read content from the attribute if available, otherwise use the default definitions from the schema tag
5854  QString content;
5855  if (hasAttribute(QString::fromLatin1("block"))) {
5856  content = readAttribute(QString::fromLatin1("block"));
5857 
5858  // split string into list to validate the content of the attribute
5860  for (int i = 0; i < values.count(); i++) {
5861  const QString value = values.at(i);
5862  if (!allowedContent.contains(value) && (value != QString::fromLatin1("#all"))) {
5863  attributeContentError("block", elementName, value);
5864  return NamedSchemaComponent::BlockingConstraints();
5865  }
5866 
5867  if ((value == QString::fromLatin1("#all")) && values.count() != 1) {
5868  error(QtXmlPatterns::tr("%1 attribute of %2 element must either contain %3 or the other values.")
5869  .arg(formatAttribute("block"))
5870  .arg(formatElement(elementName))
5871  .arg(formatData("#all")));
5872  return NamedSchemaComponent::BlockingConstraints();
5873  }
5874  }
5875  } else {
5876  // content of the default value has been validated in parseSchema already
5877  content = m_blockDefault;
5878  }
5879 
5880  QSet<QString> contentSet = content.split(QLatin1Char(' '), QString::SkipEmptyParts).toSet();
5881 
5882  // if the '#all' tag is defined, we return all allowed values
5883  if (contentSet.contains(QString::fromLatin1("#all"))) {
5884  return allowedConstraints;
5885  } else { // return the values from content set that intersects with the allowed values
5886  contentSet.intersect(allowedContent);
5887 
5888  NamedSchemaComponent::BlockingConstraints constraints;
5889 
5890  if (contentSet.contains(QString::fromLatin1("restriction")))
5891  constraints |= NamedSchemaComponent::RestrictionConstraint;
5892  if (contentSet.contains(QString::fromLatin1("extension")))
5893  constraints |= NamedSchemaComponent::ExtensionConstraint;
5894  if (contentSet.contains(QString::fromLatin1("substitution")))
5895  constraints |= NamedSchemaComponent::SubstitutionConstraint;
5896 
5897  return constraints;
5898  }
5899 }
5900 
5902 {
5903  const XsdXPathExpression::Ptr expression(new XsdXPathExpression());
5904 
5905  const QList<QXmlName> namespaceBindings = m_namespaceSupport.namespaceBindings();
5906  QXmlName emptyName;
5907  for (int i = 0; i < namespaceBindings.count(); ++i) {
5908  if (namespaceBindings.at(i).prefix() == StandardPrefixes::empty)
5909  emptyName = namespaceBindings.at(i);
5910  }
5911 
5912  expression->setNamespaceBindings(namespaceBindings);
5913 
5914  QString xpathDefaultNamespace;
5915  if (hasAttribute(QString::fromLatin1("xpathDefaultNamespace"))) {
5916  xpathDefaultNamespace = readAttribute(QString::fromLatin1("xpathDefaultNamespace"));
5917  if (xpathDefaultNamespace != QString::fromLatin1("##defaultNamespace") &&
5918  xpathDefaultNamespace != QString::fromLatin1("##targetNamespace") &&
5919  xpathDefaultNamespace != QString::fromLatin1("##local")) {
5920  if (!isValidUri(xpathDefaultNamespace)) {
5921  attributeContentError("xpathDefaultNamespace", elementName, xpathDefaultNamespace, BuiltinTypes::xsAnyURI);
5922  return expression;
5923  }
5924  }
5925  } else {
5926  xpathDefaultNamespace = m_xpathDefaultNamespace;
5927  }
5928 
5929  AnyURI::Ptr namespaceURI;
5930  if (xpathDefaultNamespace == QString::fromLatin1("##defaultNamespace")) {
5931  if (!emptyName.isNull())
5932  namespaceURI = AnyURI::fromLexical(m_namePool->stringForNamespace(emptyName.namespaceURI()));
5933  } else if (xpathDefaultNamespace == QString::fromLatin1("##targetNamespace")) {
5934  if (!m_targetNamespace.isEmpty())
5935  namespaceURI = AnyURI::fromLexical(m_targetNamespace);
5936  } else if (xpathDefaultNamespace == QString::fromLatin1("##local")) {
5937  // it is absent
5938  } else {
5939  namespaceURI = AnyURI::fromLexical(xpathDefaultNamespace);
5940  }
5941  if (namespaceURI) {
5942  if (namespaceURI->hasError()) {
5943  attributeContentError("xpathDefaultNamespace", elementName, xpathDefaultNamespace, BuiltinTypes::xsAnyURI);
5944  return expression;
5945  }
5946 
5947  expression->setDefaultNamespace(namespaceURI);
5948  }
5949 
5950  //TODO: read the base uri if qmaintaining reader support it
5951 
5952  return expression;
5953 }
5954 
5955 QString XsdSchemaParser::readXPathAttribute(const QString &attributeName, XPathType type, const char *elementName)
5956 {
5957  const QString value = readAttribute(attributeName);
5958  if (value.isEmpty() || value.startsWith(QLatin1Char('/'))) {
5959  attributeContentError(attributeName.toLatin1(), elementName, value);
5960  return QString();
5961  }
5962 
5964 
5966  switch (type) {
5967  case XPath20: language = QXmlQuery::XPath20; break;
5970  };
5971 
5972  QXmlQuery query(language, namePool);
5973  QXmlQueryPrivate *queryPrivate = query.d;
5974 
5975  const QList<QXmlName> namespaceBindings = m_namespaceSupport.namespaceBindings();
5976  for (int i = 0; i < namespaceBindings.count(); ++i) {
5977  if (!namespaceBindings.at(i).prefix() == StandardPrefixes::empty)
5978  queryPrivate->addAdditionalNamespaceBinding(namespaceBindings.at(i));
5979  }
5980 
5981  query.setQuery(value, m_documentURI);
5982  if (!query.isValid()) {
5983  attributeContentError(attributeName.toLatin1(), elementName, value);
5984  return QString();
5985  }
5986 
5987  return value;
5988 }
5989 
5990 void XsdSchemaParser::validateIdAttribute(const char *elementName)
5991 {
5992  if (hasAttribute(QString::fromLatin1("id"))) {
5993  const QString value = readAttribute(QString::fromLatin1("id"));
5995  if (id->hasError()) {
5996  attributeContentError("id", elementName, value, BuiltinTypes::xsID);
5997  } else {
5998  if (m_idCache->hasId(value)) {
5999  error(QtXmlPatterns::tr("Component with ID %1 has been defined previously.").arg(formatData(value)));
6000  } else {
6001  m_idCache->addId(value);
6002  }
6003  }
6004  }
6005 }
6006 
6008 {
6009  return ((tag == token) && (namespaceToken == XsdSchemaToken::XML_NS_SCHEMA_URI));
6010 }
6011 
6013 {
6014  const QXmlName objectName = element->name(NamePool::Ptr(m_namePool));
6015  if (m_schema->element(objectName)) {
6016  error(QtXmlPatterns::tr("Element %1 already defined.").arg(formatElement(m_namePool->displayName(objectName))));
6017  } else {
6018  m_schema->addElement(element);
6020  }
6021 }
6022 
6024 {
6025  const QXmlName objectName = attribute->name(NamePool::Ptr(m_namePool));
6026  if (m_schema->attribute(objectName)) {
6027  error(QtXmlPatterns::tr("Attribute %1 already defined.").arg(formatAttribute(m_namePool->displayName(objectName))));
6028  } else {
6029  m_schema->addAttribute(attribute);
6031  }
6032 }
6033 
6035 {
6036  // we don't import redefinitions of builtin types, that just causes problems
6038  return;
6039 
6040  const QXmlName objectName = type->name(NamePool::Ptr(m_namePool));
6041  if (m_schema->type(objectName)) {
6042  error(QtXmlPatterns::tr("Type %1 already defined.").arg(formatType(NamePool::Ptr(m_namePool), objectName)));
6043  } else {
6044  m_schema->addType(type);
6045  if (type->isSimpleType())
6047  else
6049  }
6050 }
6051 
6053 {
6054  m_schema->addAnonymousType(type);
6055  if (type->isSimpleType())
6057  else
6059 }
6060 
6062 {
6063  const QXmlName objectName = group->name(NamePool::Ptr(m_namePool));
6064  if (m_schema->attributeGroup(objectName)) {
6065  error(QtXmlPatterns::tr("Attribute group %1 already defined.").arg(formatKeyword(NamePool::Ptr(m_namePool), objectName)));
6066  } else {
6067  m_schema->addAttributeGroup(group);
6069  }
6070 }
6071 
6073 {
6074  const QXmlName objectName = group->name(NamePool::Ptr(m_namePool));
6075  if (m_schema->elementGroup(objectName)) {
6076  error(QtXmlPatterns::tr("Element group %1 already defined.").arg(formatKeyword(NamePool::Ptr(m_namePool), objectName)));
6077  } else {
6078  m_schema->addElementGroup(group);
6080  }
6081 }
6082 
6084 {
6085  const QXmlName objectName = notation->name(NamePool::Ptr(m_namePool));
6086  if (m_schema->notation(objectName)) {
6087  error(QtXmlPatterns::tr("Notation %1 already defined.").arg(formatKeyword(NamePool::Ptr(m_namePool), objectName)));
6088  } else {
6089  m_schema->addNotation(notation);
6091  }
6092 }
6093 
6095 {
6096  const QXmlName objectName = constraint->name(NamePool::Ptr(m_namePool));
6097  if (m_schema->identityConstraint(objectName)) {
6098  error(QtXmlPatterns::tr("Identity constraint %1 already defined.").arg(formatKeyword(NamePool::Ptr(m_namePool), objectName)));
6099  } else {
6100  m_schema->addIdentityConstraint(constraint);
6102  }
6103 }
6104 
6106 {
6107  // @see http://www.w3.org/TR/xmlschema-2/#src-single-facet-value
6108  if (facets.contains(facet->type())) {
6109  error(QtXmlPatterns::tr("Duplicated facets in simple type %1.").arg(formatType(NamePool::Ptr(m_namePool), type)));
6110  return;
6111  }
6112 
6113  facets.insert(facet->type(), facet);
6114 }
6115 
TypeTable::Ptr typeTable() const
const QString & stringForLocalName(const QXmlName::LocalNameCode code) const
Definition: qnamepool_p.h:168
Error error() const
Returns the type of the current error, or NoError if no error occurred.
XsdSchemaParser(const XsdSchemaContext::Ptr &context, const XsdSchemaParserContext::Ptr &parserContext, QIODevice *device)
void addElement(const XsdElement::Ptr &element)
Definition: qxsdschema.cpp:75
Match an assertion (Assertion Definition)
Definition: qxsdfacet_p.h:116
XsdTerm::Ptr parseLocalElement(const XsdParticle::Ptr &particle, const NamedSchemaComponent::Ptr &parent)
void setDefaultNamespace(const AnyURI::Ptr &defaultNamespace)
void warning(const QString &message) const
Convenience function for calling ReportContext::warning().
Represents a XSD facet object.
Definition: qxsdfacet_p.h:93
void addType(const SchemaType::Ptr &type)
void setName(const QXmlName &name)
QString toString() const
Returns a copy of the string reference as a QString object.
Definition: qstring.cpp:8653
QString displayName(const QXmlName qName) const
Definition: qnamepool.cpp:347
static const AtomicType::Ptr xsID
XsdModelGroup::Ptr parseLocalSequence(const XsdParticle::Ptr &particle, const NamedSchemaComponent::Ptr &parent)
XsdWildcard::Ptr parseAnyAttribute()
void addAttribute(const XsdAttribute::Ptr &attribute)
Represents a XSD simpleType object.
virtual QNetworkAccessManager * networkAccessManager() const
int type
Definition: qmetatype.cpp:239
virtual TypeCategory category() const
void addSubstitutionGroupAffiliation(const XsdElement::Ptr &element, const QList< QXmlName > &elementName, const QSourceLocation &location)
bool isValid() const
Returns true if the URL is valid; otherwise returns false.
Definition: qurl.cpp:4303
Represents a XSD element object.
Definition: qxsdelement_p.h:83
static mach_timebase_info_data_t info
static QString absentNamespace()
TagValidationHandler(XsdTagScope::Type tag, XsdSchemaParser *parser, const NamePool::Ptr &namePool)
Represents a XSD attribute object.
Represents a XSD model group object.
static bool isValidUri(const QString &string)
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
QSet< T > toSet() const
Returns a QSet object with the data contained in this QList.
Definition: qset.h:309
XsdElement::Ptr element(const QXmlName &name) const
Definition: qxsdschema.cpp:82
Match a minimum inclusive (Minimum Inclusive Definition)
Definition: qxsdfacet_p.h:111
XsdAttributeGroup::Ptr attributeGroup(const QXmlName name) const
Definition: qxsdschema.cpp:195
void setItemType(const AnySimpleType::Ptr &type)
void clear()
Removes all items from the hash.
Definition: qhash.h:574
Represents a XSD identity constraint object.
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
qint64 lineNumber() const
Returns the current line number, starting with 1.
void parseSchema(ParserType parserType)
XsdAttribute::Ptr parseGlobalAttribute()
void parseSelector(const XsdIdentityConstraint::Ptr &ptr)
void addIdentityConstraint(const XsdIdentityConstraint::Ptr &constraint)
QString formatKeyword(const QString &keyword)
XsdTerm::Ptr parseReferredGroup(const XsdParticle::Ptr &particle)
void parseComplexContentExtension(const XsdComplexType::Ptr &complexType)
virtual bool hasError() const
The element is defined locally as child of a complex type or model group definition.
bool open(OpenMode flags)
Opens the file using OpenMode mode, returning true if successful; otherwise false.
Definition: qfile.cpp:1064
The attribute use has a fixed value set.
void addSimpleListType(const XsdSimpleType::Ptr &simpleType, const QXmlName &typeName, const QSourceLocation &location)
void parseList(const XsdSimpleType::Ptr &ptr)
XsdAnnotation::Ptr parseAnnotation()
QString readXPathAttribute(const QString &attributeName, XPathType type, const char *elementName)
void addRedefinedAttributeGroups(const XsdAttributeGroup::Ptr &redefinedGroup, const XsdAttributeGroup::Ptr &group)
QueryLanguage
Specifies whether you want QXmlQuery to interpret the input to setQuery() as an XQuery or as an XSLT ...
Definition: qxmlquery.h:82
A smart pointer very similar to std::auto_ptr.
Definition: qautoptr_p.h:73
XsdModelGroup::Ptr parseChoice(const NamedSchemaComponent::Ptr &parent)
static NodeName toToken(const QString &value)
QString formatType(const NamePool::Ptr &np, const T &type)
Formats ItemType and SequenceType.
The QNetworkReply class contains the data and headers for a request sent with QNetworkAccessManager.
Definition: qnetworkreply.h:65
XsdTerm::Ptr term() const
void setContext(const NamedSchemaComponent::Ptr &component)
Scope::Ptr scope() const
void setSelector(const XsdXPathExpression::Ptr &selector)
XsdIdentityConstraint::Ptr identityConstraint(const QXmlName &name) const
Definition: qxsdschema.cpp:258
XsdIdentityConstraint::Ptr parseKey()
void setQuery(const QString &sourceCode, const QUrl &documentURI=QUrl())
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qxmlquery.cpp:441
XsdComplexType::OpenContent::Ptr parseOpenContent()
void parseSimpleContent(const XsdComplexType::Ptr &complexType)
void setDerivationConstraints(const SchemaType::DerivationConstraints &constraints)
static AtomicValue::Ptr fromLexical(const NamePool::Ptr &np, const QString &strNumeric)
XsdComplexType::Ptr parseLocalComplexType()
ValueConstraint::Ptr valueConstraint() const
void addAttributeUse(const XsdAttributeUse::Ptr &use)
void setParticles(const XsdParticle::List &particles)
bool isEndElement() const
Returns true if tokenType() equals EndElement ; otherwise returns false.
Definition: qxmlstream.h:338
The attribute is not allowed to be there.
void setUri(const QUrl &newUri)
Sets the URI to newUri.
XsdSchemaResolver::Ptr resolver() const
void validateIdAttribute(const char *elementName)
void addIdentityConstraint(const XsdIdentityConstraint::Ptr &constraint)
The attribute can be there but doesn&#39;t need to.
The model group contains elements only.
void addAttributeGroup(const XsdAttributeGroup::Ptr &group)
Definition: qxsdschema.cpp:188
StorageType storedValue() const
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
Definition: qstring.cpp:3734
XsdDocumentation::Ptr parseDocumentation()
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
void setLine(qint64 newLine)
Sets the line number to newLine.
QStringRef name() const
Returns the local name of a StartElement, EndElement, or an EntityReference.
QXmlName::NamespaceCode allocateNamespace(const QString &uri)
Definition: qnamepool_p.h:202
bool isValid() const
Returns true if this query is valid.
Definition: qxmlquery.cpp:885
void setIsAbstract(bool abstract)
Represents a XSD wildcard object.
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
const QLatin1String XSI("http://www.w3.org/2001/XMLSchema-instance")
void setMinimumOccurs(unsigned int occurrence)
void addField(const XsdXPathExpression::Ptr &field)
Represents a XSD complexType object.
NamedSchemaComponent::BlockingConstraints readBlockingConstraintAttribute(const NamedSchemaComponent::BlockingConstraints &allowedConstraints, const char *elementName)
QExplicitlySharedDataPointer< XsdAttributeUse > Ptr
void addAdditionalNamespaceBinding(const QXmlName &binding)
Definition: qxmlquery_p.h:272
XsdSimpleType::List simpleTypes() const
Definition: qxsdschema.cpp:138
void resolveComplexContentType(const XsdComplexType::Ptr &complexType, bool effectiveMixed)
bool atEnd() const
Returns true if the reader has read until the end of the XML document, or if an error() has occurred ...
Definition: qxmlstream.cpp:590
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)
void setSubstitutionGroupExclusions(const SchemaType::DerivationConstraints &exclusions)
QSourceLocation currentSourceLocation() const
The attribute use has a default value set.
A helper class for attribute reference resolving.
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
bool hasAttribute(const QString &namespaceURI, const QString &localName) const
Returns true if the current element has an attribute whose name is namespaceURI and local name is loc...
QXmlName createAnonymousName(const QString &targetNamespace) const
XsdModelGroup::List elementGroups() const
Definition: qxsdschema.cpp:223
bool isCharacters() const
Returns true if tokenType() equals Characters ; otherwise returns false.
Definition: qxmlstream.h:339
XsdSchemaParserContext * m_parserContext
The reference points to an attribute group.
static const uint base
Definition: qurl.cpp:268
bool contains(const Key &key) const
Returns true if the hash contains an item with the key; otherwise returns false.
Definition: qhash.h:872
XsdIdentityConstraint::Ptr parseKeyRef(const XsdElement::Ptr &element)
void setType(const AnySimpleType::Ptr &type)
bool isRelative() const
Returns true if the URL is relative; otherwise returns false.
Definition: qurl.cpp:5880
void setDerivationMethod(DerivationMethod method)
XsdAttributeUse::Ptr parseLocalAttribute(const NamedSchemaComponent::Ptr &parent)
QExplicitlySharedDataPointer< XsdIdCache > Ptr
Definition: qxsdidcache_p.h:77
QString prefix(const QXmlNamePool &query) const
Returns the prefix.
Definition: qxmlname.cpp:370
void addIncludedSchemas(const NamespaceSet &schemas)
The QXmlNamePool class is a table of shared strings referenced by instances of QXmlName.
Definition: qxmlnamepool.h:69
ContentType::Ptr contentType() const
T * data() const
Definition: qautoptr_p.h:149
void addKeyReference(const XsdElement::Ptr &element, const XsdIdentityConstraint::Ptr &keyRef, const QXmlName &name, const QSourceLocation &location)
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
void setProcessContents(ProcessContents contents)
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition: qhash.h:753
void setDefaultOpenContent(const XsdComplexType::OpenContent::Ptr &openContent, bool appliesToEmpty)
void addElement(const XsdElement::Ptr &element)
SchemaType::Ptr type() const
QExplicitlySharedDataPointer< XsdSchemaContext > Ptr
Q_CORE_EXPORT QTextStream & fixed(QTextStream &s)
void setMaximumOccurs(unsigned int occurrence)
The element has a default value set.
Match an enumeration (Enumeration Definition)
Definition: qxsdfacet_p.h:115
static const SchemaType::Ptr xsAnyType
static AtomicValue::Ptr fromLexical(const QString &val)
Definition: qboolean.cpp:120
QStringRef namespaceUri() const
Returns the namespaceUri of a StartElement or EndElement.
void addIdentityConstraint(const XsdIdentityConstraint::Ptr &constraint)
Definition: qxsdschema.cpp:251
static XsdParticle::List collectGroupRef(const XsdModelGroup::Ptr &group)
void parseComplexContent(const XsdComplexType::Ptr &complexType, bool *mixed)
T * data() const
Returns a pointer to the shared data object.
Definition: qshareddata.h:145
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
XsdAttributeUse::Ptr parseReferredAttributeGroup()
unsigned int maximumOccurs() const
No constraints at all: the item must simply be well-formed XML.
The reference points to a model group.
void addRedefinedGroups(const XsdModelGroup::Ptr &redefinedGroup, const XsdModelGroup::Ptr &group)
QLocale::Language language
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
void addImportedSchemas(const NamespaceSet &schemas)
const TCastTarget * as() const
ComponentLocationHash m_componentLocationHash
QSet< T > & intersect(const QSet< T > &other)
Definition: qset.h:256
Match the minimum length (Minimum Length Definition)
Definition: qxsdfacet_p.h:105
void addNotation(const XsdNotation::Ptr &notation)
Definition: qxsdschema.cpp:230
void addAnnotation(const XsdAnnotation::Ptr &annotation)
static bool isEmpty(const char *str)
There must be a top-level declaration for the item available, or the item must have an xsi:type...
unsigned int minimumOccurs() const
void setFacets(const XsdFacet::Hash &facets)
XsdParticle::List particles() const
XsdComplexType::OpenContent::Ptr m_defaultOpenContent
const char * typeName
Definition: qmetatype.cpp:239
static QString formatElement(const QString &element)
Formats element name.
void setExpression(const QString &expression)
Namespaces in the namespaces set are not allowed.
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
void parseSimpleContentExtension(const XsdComplexType::Ptr &complexType)
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
A helper class for automatically handling namespace scopes of elements.
void addAllGroupCheck(const XsdReference::Ptr &reference)
bool parseMinMaxConstraint(const XsdParticle::Ptr &particle, const char *tagName)
void setTargetNamespaceExtended(const QString &targetNamespace)
void setWxsSuperType(const SchemaType::Ptr &type)
QString readQNameAttribute(const QString &typeAttribute, const char *elementName)
The resource loader will report no error and return an empty QNetworkReply.
Represents a XSD assertion object.
Represents a XSD particle object.
void setIncludedSchemas(const NamespaceSet &schemas)
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
XsdModelGroup::Ptr elementGroup(const QXmlName &name) const
Definition: qxsdschema.cpp:216
const QLatin1String XML("http://www.w3.org/XML/1998/namespace")
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
XsdNotation::Ptr notation(const QXmlName &name) const
Definition: qxsdschema.cpp:237
bool isEntityReference() const
Returns true if tokenType() equals EntityReference ; otherwise returns false.
Definition: qxmlstream.h:344
The namespace for the internal API of QtXmlPatterns.
The element has a fixed value set.
XsdApplicationInformation::Ptr parseAppInfo()
const_iterator insert(const T &value)
Definition: qset.h:179
The QSourceLocation class identifies a location in a resource by URI, line, and column.
XsdXPathExpression::Ptr test() const
static const char * data(const QByteArray &arr)
void setDerivationMethod(DerivationMethod method)
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal...
Definition: qstring.h:654
XsdNotation::List notations() const
Definition: qxsdschema.cpp:244
Represents a XSD annotation object.
void setIsAbstract(bool abstract)
QExplicitlySharedDataPointer< XsdParticle > Ptr
int count() const
Definition: qset.h:178
Represents the XSD attributeGroup object.
Represents a XSD notation object, which should not be confused with the atomic type xs:NOTATION...
const T * ptr(const T &t)
void setWildcard(const XsdWildcard::Ptr &wildcard)
Describes the value constraint of an attribute.
void addId(const QString &id)
Definition: qxsdidcache.cpp:51
QByteArray toLatin1() const Q_REQUIRED_RESULT
Returns a Latin-1 representation of the string as a QByteArray.
Definition: qstring.cpp:3993
void setTerm(const XsdTerm::Ptr &term)
void addAttributeUse(const XsdAttributeUse::Ptr &use)
void addComplexBaseType(const XsdComplexType::Ptr &complexType, const QXmlName &baseName, const QSourceLocation &location, const XsdFacet::Hash &facets=XsdFacet::Hash())
void addRedefinedSchemas(const NamespaceSet &schemas)
bool value() const
Definition: qboolean_p.h:109
void setDocumentURI(const QUrl &uri)
quint16 values[128]
QXmlQueryPrivate * d
Definition: qxmlquery.h:149
XsdComplexType::List complexTypes() const
Definition: qxsdschema.cpp:153
static QString formatData(const QString &data)
void addSubstitutionGroupType(const XsdElement::Ptr &element)
void setTargetNamespace(const QXmlName::NamespaceCode code)
QExplicitlySharedDataPointer< XsdFacet > Ptr
Definition: qxsdfacet_p.h:96
void setMemberTypes(const AnySimpleType::List &types)
Base class for tokenizers that reads XML formats. This is XSLTTokenizer, and the W3C XML Schema parse...
SchemaType::Ptr type(const QXmlName &name) const
Definition: qxsdschema.cpp:124
void setType(const SchemaType::Ptr &type)
QExplicitlySharedDataPointer< OpenContent > Ptr
void addAssertion(const XsdAssertion::Ptr &assertion)
QXmlName baseTypeNameOfType(const SchemaType::Ptr &type) const
virtual QXmlName name(const NamePool::Ptr &namePool) const
void setNamespaceBindings(const QList< QXmlName > &bindings)
Match a whitespace rule (White Space Definition)
Definition: qxsdfacet_p.h:108
Match a maximum inclusive (Maximum Inclusive Definition)
Definition: qxsdfacet_p.h:109
void copyDataTo(const XsdSchemaResolver::Ptr &other) const
void setWxsSuperType(const SchemaType::Ptr &type)
bool isStartElement() const
Returns true if tokenType() equals StartElement ; otherwise returns false.
Definition: qxmlstream.h:337
QHash< XsdTagScope::Type, XsdStateMachine< XsdSchemaToken::NodeName > > m_stateMachines
static const AtomicType::Ptr xsNonNegativeInteger
void setContext(const NamedSchemaComponent::Ptr &component)
The constraint is an unique constraint.
virtual void error(const QString &msg)
QString localName(const QXmlNamePool &query) const
Returns the local name.
Definition: qxmlname.cpp:387
Implements the value instance of the xs:boolean type.
Definition: qboolean_p.h:69
Match some double digits (Fraction Digits Definition)
Definition: qxsdfacet_p.h:114
QStringRef qualifiedName() const
Returns the qualified name of a StartElement or EndElement;.
static AnyURI::Ptr fromLexical(const QString &value, const TReportContext &context, const SourceLocationReflection *const r)
Constructs a xs:anyURI value from the lexical representation value.
Definition: qanyuri_p.h:153
Represents instances of derived xs:string types, such as xs:normalizedString.
static QNetworkReply * load(const QUrl &uri, QNetworkAccessManager *const networkManager, const ReportContext::Ptr &context, ErrorHandling handling=FailOnError)
Helper function that do NetworkAccessDelegator::get(), but does it blocked.
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
QString join(const QString &sep) const
Joins all the string list&#39;s strings into a single string with each element separated by the given sep...
Definition: qstringlist.h:162
void addEnumerationFacetValue(const AtomicValue::Ptr &facetValue, const NamespaceSupport &namespaceSupport)
void addElementGroup(const XsdModelGroup::Ptr &group)
void addComponentLocationHash(const QHash< NamedSchemaComponent::Ptr, QSourceLocation > &hash)
XsdAttributeGroup::Ptr parseNamedAttributeGroup()
NamespaceCode namespaceURI() const
Definition: qnamepool_p.h:503
Match some integer digits (Total Digits Definition)
Definition: qxsdfacet_p.h:113
XsdStateMachine< XsdSchemaToken::NodeName > m_machine
XsdModelGroup::Ptr parseNamedGroup()
bool maximumOccursUnbounded() const
NamespaceConstraint::Ptr namespaceConstraint() const
XsdComplexType::Ptr parseGlobalComplexType()
void setCategory(TypeCategory category)
The QXmlName class represents the name of an XML node, in an efficient, namespace-aware way...
Definition: qxmlname.h:58
void setRedefinedSchemas(const NamespaceSet &schemas)
XsdSimpleType::Ptr parseGlobalSimpleType()
void setDisallowedSubstitutions(const BlockingConstraints &substitutions)
The QFile class provides an interface for reading from and writing to files.
Definition: qfile.h:65
static const AtomicType::Ptr xsQName
QString trimmed(QString source)
Definition: generator.cpp:233
virtual bool isReference() const
Definition: qxsdterm.cpp:63
The reference points to an attribute use.
QString readNameAttribute(const char *elementName)
void setIsNillable(bool nillable)
XsdAlternative::Ptr parseAlternative()
void parseComplexContentRestriction(const XsdComplexType::Ptr &complexType)
QString simplified() const Q_REQUIRED_RESULT
Returns a string that has whitespace removed from the start and the end, and that has each sequence o...
Definition: qstring.cpp:4415
Match the exact length (Length Definition)
Definition: qxsdfacet_p.h:104
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
void setCompositor(ModelCompositor compositor)
void removeSimpleRestrictionBase(const XsdSimpleType::Ptr &type)
void addAnonymousType(const SchemaType::Ptr &type)
Definition: qxsdschema.cpp:168
qint64 columnNumber() const
Returns the current column number, starting with 0.
static const SchemaType::Ptr xsAnySimpleType
Implements the parsing of XML schema file.
Match a regular expression (Pattern Definition)
Definition: qxsdfacet_p.h:107
static QTestResult::TestLocation location
Definition: qtestresult.cpp:63
void setAttributeWildcard(const XsdWildcard::Ptr &wildcard)
void convertName(const QString &qualified, NamespaceSupport::NameType type, QXmlName &name)
Describes the scope of an attribute.
const QString & stringForNamespace(const QXmlName::NamespaceCode code) const
Definition: qnamepool_p.h:180
Represents a XSD attribute use object.
void setScope(const Scope::Ptr &scope)
QXmlStreamNamespaceDeclarations namespaceDeclarations() const
If the state() is StartElement , this function returns the element&#39;s namespace declarations.
XsdWildcard::Ptr parseAny(const XsdParticle::Ptr &particle)
XsdAssertion::Ptr parseAssertion(const XsdSchemaToken::NodeName &nodeName, const XsdTagScope::Type &tag)
void addAnonymousType(const SchemaType::Ptr &type)
QXmlName allocateQName(const QString &uri, const QString &localName, const QString &prefix=QString())
Definition: qnamepool.cpp:251
XsdModelGroup::Ptr parseAll(const NamedSchemaComponent::Ptr &parent)
void addFacet(const XsdFacet::Ptr &facet, XsdFacet::Hash &facets, const SchemaType::Ptr &type)
void attributeContentError(const char *attributeName, const char *elementName, const QString &value, const SchemaType::Ptr &type=SchemaType::Ptr())
XsdAttribute::List attributes() const
Definition: qxsdschema.cpp:110
void setImportedSchemas(const NamespaceSet &schemas)
The element is defined globally as child of the schema object.
ValueConstraint::Ptr valueConstraint() const
virtual bool isModelGroup() const
Definition: qxsdterm.cpp:53
bool hasId(const QString &id) const
Definition: qxsdidcache.cpp:59
QExplicitlySharedDataPointer< XsdElement > Ptr
Definition: qxsdelement_p.h:86
void setScope(const Scope::Ptr &scope)
void setTargetNamespace(const QString &targetNamespace)
Definition: qxsdschema.cpp:65
XsdAttribute::Ptr attribute(const QXmlName &name) const
Definition: qxsdschema.cpp:103
A helper class for element and group reference resolving.
QString readAttribute(const QString &localName, const QString &namespaceURI=QString()) const
Returns the value for attribute by name name.
bool parse(ParserType parserType=TopLevelParser)
bool exactMatch(const QString &str) const
Returns true if str is matched exactly by this regular expression; otherwise returns false...
Definition: qregexp.cpp:4094
void addElementGroup(const XsdModelGroup::Ptr &group)
Definition: qxsdschema.cpp:209
XsdAttributeGroup::List attributeGroups() const
Definition: qxsdschema.cpp:202
static const AtomicType::Ptr xsBoolean
static const AtomicType::Ptr xsNCName
void parseSimpleRestriction(const XsdSimpleType::Ptr &ptr)
void setValueConstraint(const ValueConstraint::Ptr &constraint)
void parseSimpleContentRestriction(const XsdComplexType::Ptr &complexType)
static const AtomicType::Ptr xsPositiveInteger
void addAttributeType(const XsdAttribute::Ptr &attribute, const QXmlName &typeName, const QSourceLocation &location)
The attribute is defined locally as child of a complex type or attribute group definition.
QStringList split(const QString &sep, SplitBehavior behavior=KeepEmptyParts, Qt::CaseSensitivity cs=Qt::CaseSensitive) const Q_REQUIRED_RESULT
Splits the string into substrings wherever sep occurs, and returns the list of those strings...
Definition: qstring.cpp:6526
Represents instances of derived xs:integer types, such as xs:byte.
XsdModelGroup::Ptr parseSequence(const NamedSchemaComponent::Ptr &parent)
void addElementType(const XsdElement::Ptr &element, const QXmlName &typeName, const QSourceLocation &location)
XsdSchemaResolver * m_schemaResolver
void addNotation(const XsdNotation::Ptr &notation)
QExplicitlySharedDataPointer< XsdReference > Ptr
static QString formatURI(const NamePool::Ptr &np, const QXmlName::NamespaceCode &uri)
Formats uri, that&#39;s considered to be a URI, for display.
Definition: qanyuri_p.h:202
ModelCompositor compositor() const
Namespaces in the namespaces set are allowed.
If the item has a uniquely determined declaration available, it must be valid with respect to that de...
Represents a XSD alternative object.
XsdSimpleType::Ptr parseLocalSimpleType()
void setProhibitedSubstitutions(const BlockingConstraints &substitutions)
QList< QXmlName > namespaceBindings() const
QString readNamespaceAttribute(const QString &attributeName, const char *elementName)
static QString formatAttribute(const QString &attribute)
Formats attribute name.
QStringRef text() const
Returns the text of Characters , Comment , DTD , or EntityReference.
QString errorString() const
Returns the error message that was set with raiseError().
void addSimpleUnionTypes(const XsdSimpleType::Ptr &simpleType, const QList< QXmlName > &typeNames, const QSourceLocation &location)
A namespace class that contains identifiers for the different scopes a tag from the xml schema spec c...
The attribute has a fixed value set.
static bool isQName(const QString &qName)
QUrl resolved(const QUrl &relative) const
Returns the result of the merge of this URL with relative.
Definition: qurl.cpp:5819
The attribute is defined globally as child of the schema object.
void addType(const SchemaType::Ptr &type)
Definition: qxsdschema.cpp:117
The resource loader will report the error via the report context.
void validate(XsdSchemaToken::NodeName token)
The QIODevice class is the base interface class of all I/O devices in Qt.
Definition: qiodevice.h:66
void parseUnion(const XsdSimpleType::Ptr &ptr)
void removeComplexBaseType(const XsdComplexType::Ptr &type)
void setType(const SchemaType::Ptr &type)
Represents a XSD documentation object.
XsdXPathExpression::Ptr readXPathExpression(const char *elementName)
void addAttributeGroup(const XsdAttributeGroup::Ptr &group)
The complex type has further elements or attributes but no text as content.
void parseField(const XsdIdentityConstraint::Ptr &ptr)
void addAlternativeType(const XsdAlternative::Ptr &alternative, const QXmlName &typeName, const QSourceLocation &location)
void setTypeTable(const TypeTable::Ptr &table)
SchemaType::DerivationConstraints readDerivationConstraintAttribute(const SchemaType::DerivationConstraints &allowedConstraints, const char *elementName)
XsdModelGroup::Ptr parseLocalAll(const XsdParticle::Ptr &particle, const NamedSchemaComponent::Ptr &parent)
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
QExplicitlySharedDataPointer< XsdAttributeReference > Ptr
static bool isNCName(const QStringRef &ncName)
Determines whether c is a valid instance of production [4]NCName in the XML 1.0 Namespaces specificat...
Definition: qxmlutils.cpp:377
The complex type has no further content.
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
bool processName(const QString &qualifiedName, NameType type, QXmlName &name) const
void addComplexContentType(const XsdComplexType::Ptr &complexType, const XsdParticle::Ptr &content, bool mixed)
Represents a XSD assertion object.
The reference points to an element.
static const AtomicType::Ptr xsAnyURI
bool isSchemaTag(XsdSchemaToken::NodeName tag, XsdSchemaToken::NodeName token, XsdSchemaToken::NodeName namespaceToken) const
void setTest(const XsdXPathExpression::Ptr &test)
void setPrefixes(const QXmlStreamNamespaceDeclarations &declarations)
ElementNamespaceHandler(const XsdSchemaToken::NodeName &tag, XsdSchemaParser *parser)
virtual QXmlName name(const NamePool::Ptr &namePool) const
virtual QXmlName name(const NamePool::Ptr &np) const =0
Returns the name of the type.
XsdElement::List elements() const
Definition: qxsdschema.cpp:89
Describes the open content object of a complex type.
void setMaximumOccursUnbounded(bool unbounded)
bool isNull() const
Returns true if this QXmlName is not initialized with a valid combination of {namespace URI}...
Definition: qxmlname.cpp:224
Match the maximum length (Maximum Length Definition)
Definition: qxsdfacet_p.h:106
The QXmlQuery class performs XQueries on XML data, or on non-XML data modeled to look like XML...
Definition: qxmlquery.h:79
Helper class for keeping track of all existing IDs in a schema.
Definition: qxsdidcache_p.h:74
static const AtomicType::Ptr xsToken
void setValueConstraint(const ValueConstraint::Ptr &constraint)
The constraint is a key constraint.
void addAttribute(const XsdAttribute::Ptr &attribute)
Definition: qxsdschema.cpp:96
XsdIdentityConstraint::Ptr parseUnique()
static AtomicValue::Ptr fromLexical(const NamePool::Ptr &np, const QString &lexical)
XsdModelGroup::Ptr parseLocalChoice(const XsdParticle::Ptr &particle, const NamedSchemaComponent::Ptr &parent)
The QList class is a template class that provides lists.
Definition: qdatastream.h:62
void addSimpleRestrictionBase(const XsdSimpleType::Ptr &simpleType, const QXmlName &baseName, const QSourceLocation &location)
Scope::Ptr scope() const
int removeAll(const T &t)
Removes all occurrences of value in the list and returns the number of entries removed.
Definition: qlist.h:770
void setTargetNamespace(const QString &targetNamespace)
void removeAt(int i)
Removes the item at index position i.
Definition: qlist.h:480