1 /****************************************************************************
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
6 ** This file is part of the QtXmlPatterns module of the Qt Toolkit.
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.
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.
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.
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.
40 ****************************************************************************/
42 #include "qxsdschemaparser_p.h"
44 #include "private/qxmlutils_p.h"
45 #include "qacceltreeresourceloader_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"
54 #include "qxsdattributereference_p.h"
55 #include "qxsdreference_p.h"
56 #include "qxsdschematoken_p.h"
58 #include <QtCore/QFile>
59 #include <QtXmlPatterns/QXmlQuery>
64 * @page schema_overview Overview
65 * @section structure_and_components Structure and Components
67 * The schema validator code consists of 4 major components
70 * <dt>The schema parser (QPatternist::XsdSchemaParser)</dt>
71 * <dd>This component parses a XML document that is supplied via a QIODevice. It creates
72 * a so called (incomplete) 'compiled schema', which is a representation of the XML Schema
73 * structure as C++ objects.
74 * As the parser is a streaming parser, it can't resolve references to types or elements/attributes
75 * in place, therefor it creates resolver tasks which are passed to the schema resolver component
76 * for resolving at a later point in time.
77 * The parser does furthermore the basic XML structure constraint checking, e.g. if all required
78 * attributes are available or the order of the elements is correct.</dd>
80 * <dt>The schema resolver (QPatternist::XsdSchemaResolver)</dt>
81 * <dd>This component is activated after the schema parser component has been finished the parsing
82 * of all schemas. The resolver has been supplied with resolve tasks by the schema parser that
83 * it will resolve in this step now. Between working on the single resolver tasks, the resolver
84 * calls check methods from the schema checker component to make sure that some assertions are
85 * valid (e.g. no circular inheritance of types), so that the resolver can work without hassle.
86 * During resoving references to attribute or element groups it also checks for circular references
88 * At the end of that phase we have a compiled schema that is fully resolved (not necessarily valid though).</dd>
90 * <dt>The schema checker (QPatternist::XsdSchemaChecker)</dt>
91 * <dd>This component does all the schema constraint checking as given by the Schema specification.
92 * At the end of that phase we have fully resolved and valid compiled schema that can be used for validation
93 * of instance documents.</dd>
95 * <dt>The validator (QPatternist::XsdValidatingInstanceReader)</dt>
96 * <dd>This component is responsible for validating a XML instance document, provided via a QIODevice, against
97 * a valid compiled schema.</dd>
100 * @ingroup Patternist_schema
103 using namespace QPatternist;
105 namespace QPatternist
109 * @short A helper class for automatically handling namespace scopes of elements.
111 * This class should be instantiated at the beginning of each parse XYZ method.
113 class ElementNamespaceHandler
117 * Creates a new element namespace handler object.
119 * It checks whether the @p parser is on the right @p tag and it creates a new namespace
120 * context that contains the inherited and local namespace declarations.
122 ElementNamespaceHandler(const XsdSchemaToken::NodeName &tag, XsdSchemaParser *parser)
125 Q_ASSERT(m_parser->isStartElement() && (XsdSchemaToken::toToken(m_parser->name()) == tag) && (XsdSchemaToken::toToken(m_parser->namespaceUri()) == XsdSchemaToken::XML_NS_SCHEMA_URI));
127 m_parser->m_namespaceSupport.pushContext();
128 m_parser->m_namespaceSupport.setPrefixes(m_parser->namespaceDeclarations());
132 * Destroys the element namespace handler object.
134 * It destroys the local namespace context.
136 ~ElementNamespaceHandler()
138 m_parser->m_namespaceSupport.popContext();
142 XsdSchemaParser *m_parser;
146 * A helper class that checks for the right occurrence of
147 * xml tags with the help of a DFA.
149 class TagValidationHandler
152 TagValidationHandler(XsdTagScope::Type tag, XsdSchemaParser *parser, const NamePool::Ptr &namePool)
153 : m_parser(parser), m_machine(namePool)
155 Q_ASSERT(m_parser->m_stateMachines.contains(tag));
157 m_machine = m_parser->m_stateMachines.value(tag);
161 void validate(XsdSchemaToken::NodeName token)
163 if (token == XsdSchemaToken::NoKeyword) {
164 const QList<XsdSchemaToken::NodeName> tokens = m_machine.possibleTransitions();
166 QStringList elementNames;
167 for (int i = 0; i < tokens.count(); ++i)
168 elementNames.append(formatElement(XsdSchemaToken::toString(tokens.at(i))));
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(", "))));
176 if (!m_machine.proceed(token)) {
177 const QList<XsdSchemaToken::NodeName> tokens = m_machine.possibleTransitions();
179 QStringList elementNames;
180 for (int i = 0; i < tokens.count(); ++i)
181 elementNames.append(formatElement(XsdSchemaToken::toString(tokens.at(i))));
183 m_parser->error(QtXmlPatterns::tr("Element %1 is not allowed in this scope, possible elements are: %2.")
184 .arg(formatElement(XsdSchemaToken::toString(token)))
185 .arg(elementNames.join(QLatin1String(", "))));
190 void finalize() const
192 if (!m_machine.inEndState()) {
193 const QList<XsdSchemaToken::NodeName> tokens = m_machine.possibleTransitions();
195 QStringList elementNames;
196 for (int i = 0; i < tokens.count(); ++i)
197 elementNames.append(formatElement(XsdSchemaToken::toString(tokens.at(i))));
199 m_parser->error(QtXmlPatterns::tr("Child element is missing in that scope, possible child elements are: %1.")
200 .arg(elementNames.join(QLatin1String(", "))));
205 XsdSchemaParser *m_parser;
206 XsdStateMachine<XsdSchemaToken::NodeName> m_machine;
212 * Returns a list of all particles with group references that appear at any level of
213 * the given unresolved @p group.
215 static XsdParticle::List collectGroupRef(const XsdModelGroup::Ptr &group)
217 XsdParticle::List refParticles;
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));
226 if (particles.at(i)->term()->isModelGroup()) {
227 refParticles << collectGroupRef(XsdModelGroup::Ptr(particles.at(i)->term()));
235 * Helper function that works around the limited facilities of
236 * QUrl/AnyURI::fromLexical to detect invalid URIs
238 inline static bool isValidUri(const QString &string)
240 // an empty URI points to the current document as defined in RFC 2396 (4.2)
241 if (string.isEmpty())
244 // explicit check as that is not checked by the code below
245 if (string.startsWith(QLatin1String("##")))
248 const AnyURI::Ptr uri = AnyURI::fromLexical(string);
249 return (!(uri->hasError()));
252 XsdSchemaParser::XsdSchemaParser(const XsdSchemaContext::Ptr &context, const XsdSchemaParserContext::Ptr &parserContext, QIODevice *device)
253 : MaintainingReader<XsdSchemaToken, XsdTagScope::Type>(parserContext->elementDescriptions(), QSet<XsdSchemaToken::NodeName>(), context, device)
255 , m_parserContext(parserContext)
256 , m_namePool(m_parserContext->namePool())
257 , m_namespaceSupport(m_namePool)
259 m_schema = m_parserContext->schema();
260 m_schemaResolver = m_parserContext->resolver();
261 m_idCache = XsdIdCache::Ptr(new XsdIdCache());
263 setupStateMachines();
264 setupBuiltinTypeNames();
267 void XsdSchemaParser::addIncludedSchemas(const NamespaceSet &schemas)
269 m_includedSchemas += schemas;
272 void XsdSchemaParser::setIncludedSchemas(const NamespaceSet &schemas)
274 m_includedSchemas = schemas;
277 void XsdSchemaParser::addImportedSchemas(const NamespaceSet &schemas)
279 m_importedSchemas += schemas;
282 void XsdSchemaParser::setImportedSchemas(const NamespaceSet &schemas)
284 m_importedSchemas = schemas;
287 void XsdSchemaParser::addRedefinedSchemas(const NamespaceSet &schemas)
289 m_redefinedSchemas += schemas;
292 void XsdSchemaParser::setRedefinedSchemas(const NamespaceSet &schemas)
294 m_redefinedSchemas = schemas;
297 void XsdSchemaParser::setTargetNamespace(const QString &targetNamespace)
299 m_targetNamespace = targetNamespace;
302 void XsdSchemaParser::setTargetNamespaceExtended(const QString &targetNamespace)
304 m_targetNamespace = targetNamespace;
305 m_namespaceSupport.setTargetNamespace(m_namePool->allocateNamespace(m_targetNamespace));
308 void XsdSchemaParser::setDocumentURI(const QUrl &uri)
312 // prevent to get included/imported/redefined twice
313 m_includedSchemas.insert(uri);
314 m_importedSchemas.insert(uri);
315 m_redefinedSchemas.insert(uri);
318 QUrl XsdSchemaParser::documentURI() const
320 return m_documentURI;
323 bool XsdSchemaParser::isAnyAttributeAllowed() const
328 bool XsdSchemaParser::parse(ParserType parserType)
330 m_componentLocationHash.clear();
335 if (isStartElement()) {
336 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
337 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
339 if (isSchemaTag(XsdSchemaToken::Schema, token, namespaceToken)) {
340 parseSchema(parserType);
342 error(QtXmlPatterns::tr("Document is not a XML schema."));
347 m_schemaResolver->addComponentLocationHash(m_componentLocationHash);
348 m_schemaResolver->setDefaultOpenContent(m_defaultOpenContent, m_defaultOpenContentAppliesToEmpty);
350 if (QXmlStreamReader::error() != QXmlStreamReader::NoError)
351 error(errorString());
356 void XsdSchemaParser::error(const QString &msg)
358 MaintainingReader<XsdSchemaToken, XsdTagScope::Type>::error(msg, XsdSchemaContext::XSDError);
361 void XsdSchemaParser::attributeContentError(const char *attributeName, const char *elementName, const QString &value, const SchemaType::Ptr &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(m_namePool, type)));
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)));
377 void XsdSchemaParser::parseSchema(ParserType parserType)
379 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Schema, this);
381 validateElement(XsdTagScope::Schema);
385 if (parserType == TopLevelParser) {
386 if (hasAttribute(QString::fromLatin1("targetNamespace"))) {
387 m_targetNamespace = readNamespaceAttribute(QString::fromLatin1("targetNamespace"), "schema");
389 } else if (parserType == IncludeParser) {
390 // m_targetNamespace is set to the target namespace of the including schema at this point
392 if (hasAttribute(QString::fromLatin1("targetNamespace"))) {
393 const QString targetNamespace = readNamespaceAttribute(QString::fromLatin1("targetNamespace"), "schema");
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)));
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
404 QString targetNamespace;
405 if (hasAttribute(QString::fromLatin1("targetNamespace"))) {
406 targetNamespace = readNamespaceAttribute(QString::fromLatin1("targetNamespace"), "schema");
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)));
414 } else if (parserType == RedefineParser) {
415 // m_targetNamespace is set to the target namespace of the redefining schema at this point
417 if (hasAttribute(QString::fromLatin1("targetNamespace"))) {
418 const QString targetNamespace = readNamespaceAttribute(QString::fromLatin1("targetNamespace"), "schema");
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)));
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);
435 m_attributeFormDefault = value;
437 m_attributeFormDefault = QString::fromLatin1("unqualified");
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);
447 m_elementFormDefault = value;
449 m_elementFormDefault = QString::fromLatin1("unqualified");
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);
466 m_blockDefault = blockDefault;
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);
484 m_finalDefault = finalDefault;
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);
497 m_xpathDefaultNamespace = xpathDefaultNamespace;
499 m_xpathDefaultNamespace = QString::fromLatin1("##local");
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
507 if (hasAttribute(QString::fromLatin1("version"))) {
508 const QString version = readAttribute(QString::fromLatin1("version"));
511 if (hasAttribute(CommonNamespaces::XML, QString::fromLatin1("lang"))) {
512 const QString value = readAttribute(QString::fromLatin1("lang"), CommonNamespaces::XML);
514 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);
521 validateIdAttribute("schema");
523 TagValidationHandler tagValidator(XsdTagScope::Schema, this, m_namePool);
531 if (isStartElement()) {
532 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
533 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
535 tagValidator.validate(token);
537 if (isSchemaTag(XsdSchemaToken::Include, token, namespaceToken)) {
539 } else if (isSchemaTag(XsdSchemaToken::Import, token, namespaceToken)) {
541 } else if (isSchemaTag(XsdSchemaToken::Redefine, token, namespaceToken)) {
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)) {
547 parseDefaultOpenContent();
548 } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
549 const XsdSimpleType::Ptr type = parseGlobalSimpleType();
551 } else if (isSchemaTag(XsdSchemaToken::ComplexType, token, namespaceToken)) {
552 const XsdComplexType::Ptr type = parseGlobalComplexType();
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)) {
558 XsdAttributeGroup::Ptr attributeGroup = parseNamedAttributeGroup();
559 addAttributeGroup(attributeGroup);
560 } else if (isSchemaTag(XsdSchemaToken::Element, token, namespaceToken)) {
561 const XsdElement::Ptr element = parseGlobalElement();
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);
575 tagValidator.finalize();
577 m_schema->setTargetNamespace(m_targetNamespace);
580 void XsdSchemaParser::parseInclude()
582 Q_ASSERT(isStartElement() && XsdSchemaToken::toToken(name()) == XsdSchemaToken::Include &&
583 XsdSchemaToken::toToken(namespaceUri()) == XsdSchemaToken::XML_NS_SCHEMA_URI);
585 validateElement(XsdTagScope::Include);
588 const QString schemaLocation = readAttribute(QString::fromLatin1("schemaLocation"));
590 QUrl url(schemaLocation);
591 if (url.isRelative()) {
592 Q_ASSERT(m_documentURI.isValid());
594 url = m_documentURI.resolved(url);
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.
601 m_includedSchemas.insert(url);
603 const AutoPtr<QNetworkReply> reply(AccelTreeResourceLoader::load(url, m_context->networkAccessManager(),
604 m_context, AccelTreeResourceLoader::ContinueOnError));
606 // parse the included schema by a different parser but with the same context
607 XsdSchemaParser parser(m_context, m_parserContext, reply.data());
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)) {
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);
624 validateIdAttribute("include");
626 TagValidationHandler tagValidator(XsdTagScope::Include, this, m_namePool);
634 if (isStartElement()) {
635 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
636 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
638 tagValidator.validate(token);
640 if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
641 const XsdAnnotation::Ptr annotation = parseAnnotation();
642 m_schema->addAnnotation(annotation);
649 tagValidator.finalize();
652 void XsdSchemaParser::parseImport()
654 Q_ASSERT(isStartElement() && XsdSchemaToken::toToken(name()) == XsdSchemaToken::Import &&
655 XsdSchemaToken::toToken(namespaceUri()) == XsdSchemaToken::XML_NS_SCHEMA_URI);
657 validateElement(XsdTagScope::Import);
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"))
667 .arg(formatURI(m_targetNamespace)));
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")));
679 if (hasAttribute(QString::fromLatin1("schemaLocation"))) {
680 const QString schemaLocation = readAttribute(QString::fromLatin1("schemaLocation"));
682 QUrl url(schemaLocation);
683 if (url.isRelative()) {
684 Q_ASSERT(m_documentURI.isValid());
686 url = m_documentURI.resolved(url);
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.
693 m_importedSchemas.insert(url);
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);
699 AutoPtr<QNetworkReply> reply(AccelTreeResourceLoader::load(url, m_context->networkAccessManager(),
700 m_context, AccelTreeResourceLoader::ContinueOnError));
702 // parse the included schema by a different parser but with the same context
703 XsdSchemaParser parser(m_context, m_parserContext, reply.data());
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)) {
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);
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);
725 QFile file(QString::fromLatin1(":") + importNamespace);
726 if (file.open(QIODevice::ReadOnly)) {
727 XsdSchemaParser parser(m_context, m_parserContext, &file);
728 parser.setDocumentURI(importNamespace);
729 parser.setTargetNamespace(importNamespace);
730 parser.setIncludedSchemas(m_includedSchemas);
731 parser.setImportedSchemas(m_importedSchemas);
732 parser.setRedefinedSchemas(m_redefinedSchemas);
733 if (!parser.parse(XsdSchemaParser::ImportParser)) {
736 // add indirectly loaded schemas to the list of already loaded ones
737 addIncludedSchemas(parser.m_includedSchemas);
738 addImportedSchemas(parser.m_importedSchemas);
739 addRedefinedSchemas(parser.m_redefinedSchemas);
744 // we don't import anything... that is valid according to the schema
748 validateIdAttribute("import");
750 TagValidationHandler tagValidator(XsdTagScope::Import, this, m_namePool);
758 if (isStartElement()) {
759 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
760 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
762 tagValidator.validate(token);
764 if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
765 const XsdAnnotation::Ptr annotation = parseAnnotation();
766 m_schema->addAnnotation(annotation);
773 tagValidator.finalize();
776 void XsdSchemaParser::parseRedefine()
778 Q_ASSERT(isStartElement() && XsdSchemaToken::toToken(name()) == XsdSchemaToken::Redefine &&
779 XsdSchemaToken::toToken(namespaceUri()) == XsdSchemaToken::XML_NS_SCHEMA_URI);
781 validateElement(XsdTagScope::Redefine);
784 validateIdAttribute("redefine");
786 const QString schemaLocation = readAttribute(QString::fromLatin1("schemaLocation"));
788 TagValidationHandler tagValidator(XsdTagScope::Redefine, this, m_namePool);
790 XsdSimpleType::List redefinedSimpleTypes;
791 XsdComplexType::List redefinedComplexTypes;
792 XsdModelGroup::List redefinedGroups;
793 XsdAttributeGroup::List redefinedAttributeGroups;
801 if (isStartElement()) {
802 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
803 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
805 tagValidator.validate(token);
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)) {
811 const XsdSimpleType::Ptr type = parseGlobalSimpleType();
812 redefinedSimpleTypes.append(type);
814 const QXmlName baseTypeName = m_parserContext->resolver()->baseTypeNameOfType(type);
815 if (baseTypeName != type->name(m_namePool)) {
816 error(QString::fromLatin1("redefined simple type %1 must have itself as base type").arg(formatType(m_namePool, type)));
819 } else if (isSchemaTag(XsdSchemaToken::ComplexType, token, namespaceToken)) {
820 const XsdComplexType::Ptr type = parseGlobalComplexType();
821 redefinedComplexTypes.append(type);
823 // @see http://www.w3.org/TR/xmlschema11-1/#src-redefine
826 const QXmlName baseTypeName = m_parserContext->resolver()->baseTypeNameOfType(type);
827 if (baseTypeName != type->name(m_namePool)) {
828 error(QString::fromLatin1("redefined complex type %1 must have itself as base type").arg(formatType(m_namePool, type)));
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)) {
835 const XsdAttributeGroup::Ptr group = parseNamedAttributeGroup();
836 redefinedAttributeGroups.append(group);
844 bool locationMustResolve = false;
845 if (!redefinedSimpleTypes.isEmpty() || !redefinedComplexTypes.isEmpty() ||
846 !redefinedGroups.isEmpty() || !redefinedAttributeGroups.isEmpty()) {
847 locationMustResolve = true;
850 QUrl url(schemaLocation);
851 if (url.isRelative()) {
852 Q_ASSERT(m_documentURI.isValid());
854 url = m_documentURI.resolved(url);
857 // we parse the schema given in the redefine tag into its own context
858 const XsdSchemaParserContext::Ptr redefinedContext(new XsdSchemaParserContext(m_namePool, m_context));
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.
864 m_redefinedSchemas.insert(url);
865 QNetworkReply *reply = AccelTreeResourceLoader::load(url, m_context->networkAccessManager(),
867 (locationMustResolve ? AccelTreeResourceLoader::FailOnError : AccelTreeResourceLoader::ContinueOnError));
869 // parse the included schema by a different parser but with the same context
870 XsdSchemaParser parser(m_context, redefinedContext, reply);
871 parser.setDocumentURI(url);
872 parser.setTargetNamespaceExtended(m_targetNamespace);
873 parser.setIncludedSchemas(m_includedSchemas);
874 parser.setImportedSchemas(m_importedSchemas);
875 parser.setRedefinedSchemas(m_redefinedSchemas);
876 if (!parser.parse(XsdSchemaParser::RedefineParser)) {
879 // add indirectly loaded schemas to the list of already loaded ones
880 addIncludedSchemas(parser.m_includedSchemas);
881 addImportedSchemas(parser.m_importedSchemas);
882 addRedefinedSchemas(parser.m_redefinedSchemas);
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();
894 // now we do the actual redefinition:
896 // iterate over all redefined simple types
897 for (int i = 0; i < redefinedSimpleTypes.count(); ++i) {
898 XsdSimpleType::Ptr redefinedType = redefinedSimpleTypes.at(i);
900 //TODONEXT: validation
902 // search the definition they override in the context types
904 for (int j = 0; j < contextSimpleTypes.count(); ++j) {
905 XsdSimpleType::Ptr contextType = contextSimpleTypes.at(j);
907 if (redefinedType->name(m_namePool) == contextType->name(m_namePool)) { // we found the right type
910 // 1) set name of context type to empty name
911 contextType->setName(m_parserContext->createAnonymousName(QString()));
913 // 2) set the context type as base type for the redefined type
914 redefinedType->setWxsSuperType(contextType);
916 // 3) remove the base type resolving job from the resolver as
917 // we have set the base type here explicitly
918 m_parserContext->resolver()->removeSimpleRestrictionBase(redefinedType);
920 // 4) add the redefined type to the schema
921 addType(redefinedType);
923 // 5) add the context type as anonymous type, so the resolver
924 // can resolve it further.
925 addAnonymousType(contextType);
927 // 6) remove the context type from the list
928 contextSimpleTypes.removeAt(j);
935 error(QString::fromLatin1("no matching type found to redefine simple type %1").arg(formatType(m_namePool, redefinedType)));
940 // add all remaining context simple types to the schema
941 for (int i = 0; i < contextSimpleTypes.count(); ++i) {
942 addType(contextSimpleTypes.at(i));
945 // iterate over all redefined complex types
946 for (int i = 0; i < redefinedComplexTypes.count(); ++i) {
947 XsdComplexType::Ptr redefinedType = redefinedComplexTypes.at(i);
949 //TODONEXT: validation
951 // search the definition they override in the context types
953 for (int j = 0; j < contextComplexTypes.count(); ++j) {
954 XsdComplexType::Ptr contextType = contextComplexTypes.at(j);
956 if (redefinedType->name(m_namePool) == contextType->name(m_namePool)) { // we found the right type
959 // 1) set name of context type to empty name
960 contextType->setName(m_parserContext->createAnonymousName(QString()));
962 // 2) set the context type as base type for the redefined type
963 redefinedType->setWxsSuperType(contextType);
965 // 3) remove the base type resolving job from the resolver as
966 // we have set the base type here explicitly
967 m_parserContext->resolver()->removeComplexBaseType(redefinedType);
969 // 4) add the redefined type to the schema
970 addType(redefinedType);
972 // 5) add the context type as anonymous type, so the resolver
973 // can resolve its attribute uses etc.
974 addAnonymousType(contextType);
976 // 6) remove the context type from the list
977 contextComplexTypes.removeAt(j);
984 error(QString::fromLatin1("no matching type found to redefine complex type %1").arg(formatType(m_namePool, redefinedType)));
989 // iterate over all redefined element groups
990 for (int i = 0; i < redefinedGroups.count(); ++i) {
991 const XsdModelGroup::Ptr group(redefinedGroups.at(i));
993 // @see http://www.w3.org/TR/xmlschema11-1/#src-redefine
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(m_namePool)) {
1002 referencedParticle = particles.at(i);
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(m_namePool))));
1013 if (sameNameCounter > 1) {
1014 error(QString::fromLatin1("redefined group %1 can not contain multiple references to itself").arg(formatKeyword(group->displayName(m_namePool))));
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(m_namePool) == contextGroups.at(j)->name(m_namePool)) {
1022 contextGroup = contextGroups.at(j);
1027 if (!contextGroup) { // 6.2.1
1028 error(QString::fromLatin1("redefined group %1 has no occurrence in included schema").arg(formatKeyword(group->displayName(m_namePool))));
1032 if (sameNameCounter == 1) {
1033 // there was a self reference in the redefined group, so use the
1034 // group from the included schema
1036 // set a anonymous name to the group of the included schema
1037 contextGroup->setName(m_parserContext->createAnonymousName(m_namePool->stringForNamespace(contextGroup->name(m_namePool).namespaceURI())));
1039 // replace the self-reference with the group from the included schema
1040 referencedParticle->setTerm(contextGroup);
1042 addElementGroup(group);
1044 addElementGroup(contextGroup);
1045 contextGroups.removeAll(contextGroup);
1047 // there was no self reference in the redefined group
1049 // just add the redefined group...
1050 addElementGroup(group);
1052 // we have to add them, otherwise it is not resolved and we can't validate it later
1053 contextGroup->setName(m_parserContext->createAnonymousName(m_namePool->stringForNamespace(contextGroup->name(m_namePool).namespaceURI())));
1054 addElementGroup(contextGroup);
1056 m_schemaResolver->addRedefinedGroups(group, contextGroup);
1058 // ...and forget about the group from the included schema
1059 contextGroups.removeAll(contextGroup);
1063 // iterate over all redefined attribute groups
1064 for (int i = 0; i < redefinedAttributeGroups.count(); ++i) {
1065 const XsdAttributeGroup::Ptr group(redefinedAttributeGroups.at(i));
1067 // @see http://www.w3.org/TR/xmlschema11-1/#src-redefine
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(m_namePool) == reference->referenceName())
1083 if (sameNameCounter > 1) {
1084 error(QString::fromLatin1("redefined attribute group %1 can not contain multiple references to itself").arg(formatKeyword(group->displayName(m_namePool))));
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(m_namePool) == contextGroup->name(m_namePool)) {
1093 baseGroup = contextGroup;
1098 if (!baseGroup) { // 7.2.1
1099 error(QString::fromLatin1("redefined attribute group %1 has no occurrence in included schema").arg(formatKeyword(group->displayName(m_namePool))));
1103 if (sameNameCounter == 1) {
1105 // first set an anonymous name to the attribute group from the included
1107 baseGroup->setName(m_parserContext->createAnonymousName(m_namePool->stringForNamespace(baseGroup->name(m_namePool).namespaceURI())));
1109 // iterate over the attribute uses of the redefined attribute group
1110 // and replace the self-reference with the attribute group from the
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(m_namePool) == reference->referenceName()) {
1118 reference->setReferenceName(baseGroup->name(m_namePool));
1125 // add both groups to the target schema
1126 addAttributeGroup(baseGroup);
1127 addAttributeGroup(group);
1129 contextAttributeGroups.removeAll(baseGroup);
1132 if (sameNameCounter == 0) { // 7.2
1134 // we have to add them, otherwise it is not resolved and we can't validate it later
1135 baseGroup->setName(m_parserContext->createAnonymousName(m_namePool->stringForNamespace(baseGroup->name(m_namePool).namespaceURI())));
1136 addAttributeGroup(baseGroup);
1138 m_schemaResolver->addRedefinedAttributeGroups(group, baseGroup);
1140 // just add the redefined attribute group to the target schema...
1141 addAttributeGroup(group);
1143 // ... and forget about the one from the included schema
1144 contextAttributeGroups.removeAll(baseGroup);
1148 // add all remaining context complex types to the schema
1149 for (int i = 0; i < contextComplexTypes.count(); ++i) {
1150 addType(contextComplexTypes.at(i));
1153 // add all remaining context element groups to the schema
1154 for (int i = 0; i < contextGroups.count(); ++i) {
1155 addElementGroup(contextGroups.at(i));
1158 // add all remaining context attribute groups to the schema
1159 for (int i = 0; i < contextAttributeGroups.count(); ++i) {
1160 addAttributeGroup(contextAttributeGroups.at(i));
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));
1169 const XsdAttribute::List contextAttributes = redefinedContext->schema()->attributes();
1170 for (int i = 0; i < contextAttributes.count(); ++i) {
1171 addAttribute(contextAttributes.at(i));
1174 const XsdNotation::List contextNotations = redefinedContext->schema()->notations();
1175 for (int i = 0; i < contextNotations.count(); ++i) {
1176 addNotation(contextNotations.at(i));
1179 // push all data to resolve from the context resolver to our resolver
1180 redefinedContext->resolver()->copyDataTo(m_parserContext->resolver());
1182 tagValidator.finalize();
1185 XsdAnnotation::Ptr XsdSchemaParser::parseAnnotation()
1187 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Annotation, this);
1189 validateElement(XsdTagScope::Annotation);
1192 validateIdAttribute("annotation");
1194 TagValidationHandler tagValidator(XsdTagScope::Annotation, this, m_namePool);
1196 const XsdAnnotation::Ptr annotation(new XsdAnnotation());
1204 if (isStartElement()) {
1205 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
1206 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
1208 tagValidator.validate(token);
1210 if (isSchemaTag(XsdSchemaToken::Appinfo, token, namespaceToken)) {
1211 const XsdApplicationInformation::Ptr info = parseAppInfo();
1212 annotation->addApplicationInformation(info);
1213 } else if (isSchemaTag(XsdSchemaToken::Documentation, token, namespaceToken)) {
1214 const XsdDocumentation::Ptr documentation = parseDocumentation();
1215 annotation->addDocumentation(documentation);
1222 tagValidator.finalize();
1227 XsdApplicationInformation::Ptr XsdSchemaParser::parseAppInfo()
1229 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Appinfo, this);
1231 validateElement(XsdTagScope::AppInfo);
1233 const XsdApplicationInformation::Ptr info(new XsdApplicationInformation());
1236 if (hasAttribute(QString::fromLatin1("source"))) {
1237 const QString value = readAttribute(QString::fromLatin1("source"));
1239 if (!isValidUri(value)) {
1240 attributeContentError("source", "appinfo", value, BuiltinTypes::xsAnyURI);
1244 if (!value.isEmpty()) {
1245 const AnyURI::Ptr source = AnyURI::fromLexical(value);
1246 info->setSource(source);
1250 while (!atEnd()) { //EVAL: can be anything... what to do?
1256 if (isStartElement())
1257 parseUnknownDocumentation();
1263 XsdDocumentation::Ptr XsdSchemaParser::parseDocumentation()
1265 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Documentation, this);
1267 validateElement(XsdTagScope::Documentation);
1269 const XsdDocumentation::Ptr documentation(new XsdDocumentation());
1272 if (hasAttribute(QString::fromLatin1("source"))) {
1273 const QString value = readAttribute(QString::fromLatin1("source"));
1275 if (!isValidUri(value)) {
1276 attributeContentError("source", "documentation", value, BuiltinTypes::xsAnyURI);
1277 return documentation;
1280 if (!value.isEmpty()) {
1281 const AnyURI::Ptr source = AnyURI::fromLexical(value);
1282 documentation->setSource(source);
1286 if (hasAttribute(CommonNamespaces::XML, QString::fromLatin1("lang"))) {
1287 const QString value = readAttribute(QString::fromLatin1("lang"), CommonNamespaces::XML);
1289 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;
1296 while (!atEnd()) { //EVAL: can by any... what to do?
1302 if (isStartElement())
1303 parseUnknownDocumentation();
1306 return documentation;
1309 void XsdSchemaParser::parseDefaultOpenContent()
1311 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::DefaultOpenContent, this);
1313 validateElement(XsdTagScope::DefaultOpenContent);
1315 m_defaultOpenContent = XsdComplexType::OpenContent::Ptr(new XsdComplexType::OpenContent());
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);
1325 m_defaultOpenContentAppliesToEmpty = appliesToEmpty->as<Boolean>()->value();
1327 m_defaultOpenContentAppliesToEmpty = false;
1330 if (hasAttribute(QString::fromLatin1("mode"))) {
1331 const QString mode = readAttribute(QString::fromLatin1("mode"));
1333 if (mode == QString::fromLatin1("interleave")) {
1334 m_defaultOpenContent->setMode(XsdComplexType::OpenContent::Interleave);
1335 } else if (mode == QString::fromLatin1("suffix")) {
1336 m_defaultOpenContent->setMode(XsdComplexType::OpenContent::Suffix);
1338 attributeContentError("mode", "defaultOpenContent", mode);
1342 m_defaultOpenContent->setMode(XsdComplexType::OpenContent::Interleave);
1345 validateIdAttribute("defaultOpenContent");
1347 TagValidationHandler tagValidator(XsdTagScope::DefaultOpenContent, this, m_namePool);
1355 if (isStartElement()) {
1356 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
1357 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
1359 tagValidator.validate(token);
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);
1374 tagValidator.finalize();
1377 XsdSimpleType::Ptr XsdSchemaParser::parseGlobalSimpleType()
1379 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::SimpleType, this);
1381 validateElement(XsdTagScope::GlobalSimpleType);
1383 const XsdSimpleType::Ptr simpleType(new XsdSimpleType());
1384 simpleType->setCategory(XsdSimpleType::SimpleTypeAtomic); // just to make sure it's not invalid
1387 const SchemaType::DerivationConstraints allowedConstraints(SchemaType::ExtensionConstraint | SchemaType::RestrictionConstraint | SchemaType::ListConstraint | SchemaType::UnionConstraint);
1388 simpleType->setDerivationConstraints(readDerivationConstraintAttribute(allowedConstraints, "simpleType"));
1390 const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("simpleType"));
1391 simpleType->setName(objectName);
1393 validateIdAttribute("simpleType");
1395 TagValidationHandler tagValidator(XsdTagScope::GlobalSimpleType, this, m_namePool);
1403 if (isStartElement()) {
1404 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
1405 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
1407 tagValidator.validate(token);
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);
1424 tagValidator.finalize();
1429 XsdSimpleType::Ptr XsdSchemaParser::parseLocalSimpleType()
1431 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::SimpleType, this);
1433 validateElement(XsdTagScope::LocalSimpleType);
1435 const XsdSimpleType::Ptr simpleType(new XsdSimpleType());
1436 simpleType->setCategory(XsdSimpleType::SimpleTypeAtomic); // just to make sure it's not invalid
1437 simpleType->setName(m_parserContext->createAnonymousName(m_targetNamespace));
1439 validateIdAttribute("simpleType");
1441 TagValidationHandler tagValidator(XsdTagScope::LocalSimpleType, this, m_namePool);
1449 if (isStartElement()) {
1450 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
1451 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
1453 tagValidator.validate(token);
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);
1470 tagValidator.finalize();
1475 void XsdSchemaParser::parseSimpleRestriction(const XsdSimpleType::Ptr &ptr)
1477 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Restriction, this);
1479 validateElement(XsdTagScope::SimpleRestriction);
1481 ptr->setDerivationMethod(XsdSimpleType::DerivationRestriction);
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;
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
1494 hasBaseAttribute = true;
1495 hasBaseTypeSpecified = true;
1497 validateIdAttribute("restriction");
1499 XsdFacet::Hash facets;
1500 QList<XsdFacet::Ptr> patternFacets;
1501 QList<XsdFacet::Ptr> enumerationFacets;
1502 QList<XsdFacet::Ptr> assertionFacets;
1504 TagValidationHandler tagValidator(XsdTagScope::SimpleRestriction, this, m_namePool);
1512 if (isStartElement()) {
1513 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
1514 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
1516 tagValidator.validate(token);
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")));
1530 const XsdSimpleType::Ptr type = parseLocalSimpleType();
1531 type->setContext(ptr);
1532 ptr->setWxsSuperType(type);
1533 ptr->setCategory(type->category());
1534 hasBaseTypeSpecified = true;
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);
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")));
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);
1596 AtomicValue::List multiValue;
1597 for (int i = 0; i < patternFacets.count(); ++i)
1598 multiValue << patternFacets.at(i)->multiValue();
1600 patternFacet->setMultiValue(multiValue);
1601 addFacet(patternFacet, facets, ptr);
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);
1609 AtomicValue::List multiValue;
1610 for (int i = 0; i < enumerationFacets.count(); ++i)
1611 multiValue << enumerationFacets.at(i)->multiValue();
1613 enumerationFacet->setMultiValue(multiValue);
1614 addFacet(enumerationFacet, facets, ptr);
1617 // merge all assertion facets into one facet
1618 if (!assertionFacets.isEmpty()) {
1619 const XsdFacet::Ptr assertionFacet(new XsdFacet());
1620 assertionFacet->setType(XsdFacet::Assertion);
1622 XsdAssertion::List assertions;
1623 for (int i = 0; i < assertionFacets.count(); ++i)
1624 assertions << assertionFacets.at(i)->assertions();
1626 assertionFacet->setAssertions(assertions);
1627 addFacet(assertionFacet, facets, ptr);
1630 ptr->setFacets(facets);
1632 tagValidator.finalize();
1635 void XsdSchemaParser::parseList(const XsdSimpleType::Ptr &ptr)
1637 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::List, this);
1639 validateElement(XsdTagScope::List);
1641 ptr->setCategory(XsdSimpleType::SimpleTypeList);
1642 ptr->setDerivationMethod(XsdSimpleType::DerivationList);
1643 ptr->setWxsSuperType(BuiltinTypes::xsAnySimpleType);
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;
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
1656 hasItemTypeAttribute = true;
1657 hasItemTypeSpecified = true;
1660 validateIdAttribute("list");
1662 TagValidationHandler tagValidator(XsdTagScope::List, this, m_namePool);
1670 if (isStartElement()) {
1671 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
1672 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
1674 tagValidator.validate(token);
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")));
1688 const XsdSimpleType::Ptr type = parseLocalSimpleType();
1689 type->setContext(ptr);
1690 ptr->setItemType(type);
1692 hasItemTypeSpecified = true;
1694 // add it to list of anonymous types as well
1695 addAnonymousType(type);
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")));
1710 tagValidator.finalize();
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);
1716 defaultFacet->setValue(DerivedString<TypeString>::fromLexical(m_namePool, XsdSchemaToken::toString(XsdSchemaToken::Collapse)));
1717 XsdFacet::Hash facets;
1718 facets.insert(defaultFacet->type(), defaultFacet);
1719 ptr->setFacets(facets);
1722 void XsdSchemaParser::parseUnion(const XsdSimpleType::Ptr &ptr)
1724 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Union, this);
1726 validateElement(XsdTagScope::Union);
1728 ptr->setCategory(XsdSimpleType::SimpleTypeUnion);
1729 ptr->setDerivationMethod(XsdSimpleType::DerivationUnion);
1730 ptr->setWxsSuperType(BuiltinTypes::xsAnySimpleType);
1732 // The memberTypes attribute is not allowed to be empty,
1733 // so we keep track of that
1734 bool hasMemberTypesSpecified = false;
1736 if (hasAttribute(QString::fromLatin1("memberTypes"))) {
1737 const QStringList memberTypes = readAttribute(QString::fromLatin1("memberTypes")).split(QLatin1Char(' '), QString::SkipEmptyParts);
1738 QList<QXmlName> typeNames;
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);
1746 if (!typeNames.isEmpty()) {
1747 m_schemaResolver->addSimpleUnionTypes(ptr, typeNames, currentSourceLocation()); // add to resolver
1748 hasMemberTypesSpecified = true;
1752 validateIdAttribute("union");
1754 AnySimpleType::List memberTypes;
1756 TagValidationHandler tagValidator(XsdTagScope::Union, this, m_namePool);
1764 if (isStartElement()) {
1765 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
1766 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
1768 tagValidator.validate(token);
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)) {
1774 const XsdSimpleType::Ptr type = parseLocalSimpleType();
1775 type->setContext(ptr);
1776 memberTypes.append(type);
1778 // add it to list of anonymous types as well
1779 addAnonymousType(type);
1786 if (!memberTypes.isEmpty()) {
1787 ptr->setMemberTypes(memberTypes);
1788 hasMemberTypesSpecified = true;
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")));
1799 tagValidator.finalize();
1802 XsdFacet::Ptr XsdSchemaParser::parseMinExclusiveFacet()
1804 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::MinExclusive, this);
1806 validateElement(XsdTagScope::MinExclusiveFacet);
1808 const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
1809 facet->setType(XsdFacet::MinimumExclusive);
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);
1820 facet->setFixed(fixed->as<Boolean>()->value());
1822 facet->setFixed(false); // the default value
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"));
1828 DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(m_namePool, value);
1829 if (string->hasError()) {
1830 attributeContentError("value", "minExclusive", value, BuiltinTypes::xsAnySimpleType);
1833 facet->setValue(string);
1836 validateIdAttribute("minExclusive");
1838 TagValidationHandler tagValidator(XsdTagScope::MinExclusiveFacet, this, m_namePool);
1846 if (isStartElement()) {
1847 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
1848 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
1850 tagValidator.validate(token);
1852 if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
1853 const XsdAnnotation::Ptr annotation = parseAnnotation();
1854 facet->addAnnotation(annotation);
1861 tagValidator.finalize();
1866 XsdFacet::Ptr XsdSchemaParser::parseMinInclusiveFacet()
1868 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::MinInclusive, this);
1870 validateElement(XsdTagScope::MinInclusiveFacet);
1872 const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
1873 facet->setType(XsdFacet::MinimumInclusive);
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);
1884 facet->setFixed(fixed->as<Boolean>()->value());
1886 facet->setFixed(false); // the default value
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"));
1892 DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(m_namePool, value);
1893 if (string->hasError()) {
1894 attributeContentError("value", "minInclusive", value, BuiltinTypes::xsAnySimpleType);
1897 facet->setValue(string);
1900 validateIdAttribute("minInclusive");
1902 TagValidationHandler tagValidator(XsdTagScope::MinInclusiveFacet, this, m_namePool);
1910 if (isStartElement()) {
1911 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
1912 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
1914 tagValidator.validate(token);
1916 if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
1917 const XsdAnnotation::Ptr annotation = parseAnnotation();
1918 facet->addAnnotation(annotation);
1925 tagValidator.finalize();
1930 XsdFacet::Ptr XsdSchemaParser::parseMaxExclusiveFacet()
1932 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::MaxExclusive, this);
1934 validateElement(XsdTagScope::MaxExclusiveFacet);
1936 const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
1937 facet->setType(XsdFacet::MaximumExclusive);
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);
1948 facet->setFixed(fixed->as<Boolean>()->value());
1950 facet->setFixed(false); // the default value
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"));
1956 DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(m_namePool, value);
1957 if (string->hasError()) {
1958 attributeContentError("value", "maxExclusive", value, BuiltinTypes::xsAnySimpleType);
1961 facet->setValue(string);
1964 validateIdAttribute("maxExclusive");
1966 TagValidationHandler tagValidator(XsdTagScope::MaxExclusiveFacet, this, m_namePool);
1974 if (isStartElement()) {
1975 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
1976 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
1978 tagValidator.validate(token);
1980 if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
1981 const XsdAnnotation::Ptr annotation = parseAnnotation();
1982 facet->addAnnotation(annotation);
1989 tagValidator.finalize();
1994 XsdFacet::Ptr XsdSchemaParser::parseMaxInclusiveFacet()
1996 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::MaxInclusive, this);
1998 validateElement(XsdTagScope::MaxInclusiveFacet);
2000 const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
2001 facet->setType(XsdFacet::MaximumInclusive);
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);
2012 facet->setFixed(fixed->as<Boolean>()->value());
2014 facet->setFixed(false); // the default value
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"));
2020 DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(m_namePool, value);
2021 if (string->hasError()) {
2022 attributeContentError("value", "maxInclusive", value, BuiltinTypes::xsAnySimpleType);
2025 facet->setValue(string);
2028 validateIdAttribute("maxInclusive");
2030 TagValidationHandler tagValidator(XsdTagScope::MaxInclusiveFacet, this, m_namePool);
2038 if (isStartElement()) {
2039 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
2040 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
2042 tagValidator.validate(token);
2044 if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
2045 const XsdAnnotation::Ptr annotation = parseAnnotation();
2046 facet->addAnnotation(annotation);
2053 tagValidator.finalize();
2058 XsdFacet::Ptr XsdSchemaParser::parseTotalDigitsFacet()
2060 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::TotalDigits, this);
2062 validateElement(XsdTagScope::TotalDigitsFacet);
2064 const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
2065 facet->setType(XsdFacet::TotalDigits);
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);
2076 facet->setFixed(fixed->as<Boolean>()->value());
2078 facet->setFixed(false); // the default value
2081 const QString value = readAttribute(QString::fromLatin1("value"));
2082 DerivedInteger<TypePositiveInteger>::Ptr integer = DerivedInteger<TypePositiveInteger>::fromLexical(m_namePool, value);
2083 if (integer->hasError()) {
2084 attributeContentError("value", "totalDigits", value, BuiltinTypes::xsPositiveInteger);
2087 facet->setValue(integer);
2090 validateIdAttribute("totalDigits");
2092 TagValidationHandler tagValidator(XsdTagScope::TotalDigitsFacet, this, m_namePool);
2100 if (isStartElement()) {
2101 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
2102 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
2104 tagValidator.validate(token);
2106 if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
2107 const XsdAnnotation::Ptr annotation = parseAnnotation();
2108 facet->addAnnotation(annotation);
2115 tagValidator.finalize();
2120 XsdFacet::Ptr XsdSchemaParser::parseFractionDigitsFacet()
2122 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::FractionDigits, this);
2124 validateElement(XsdTagScope::FractionDigitsFacet);
2126 const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
2127 facet->setType(XsdFacet::FractionDigits);
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);
2138 facet->setFixed(fixed->as<Boolean>()->value());
2140 facet->setFixed(false); // the default value
2143 const QString value = readAttribute(QString::fromLatin1("value"));
2144 DerivedInteger<TypeNonNegativeInteger>::Ptr integer = DerivedInteger<TypeNonNegativeInteger>::fromLexical(m_namePool, value);
2145 if (integer->hasError()) {
2146 attributeContentError("value", "fractionDigits", value, BuiltinTypes::xsNonNegativeInteger);
2149 facet->setValue(integer);
2152 validateIdAttribute("fractionDigits");
2154 TagValidationHandler tagValidator(XsdTagScope::FractionDigitsFacet, this, m_namePool);
2162 if (isStartElement()) {
2163 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
2164 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
2166 tagValidator.validate(token);
2168 if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
2169 const XsdAnnotation::Ptr annotation = parseAnnotation();
2170 facet->addAnnotation(annotation);
2177 tagValidator.finalize();
2182 XsdFacet::Ptr XsdSchemaParser::parseLengthFacet()
2184 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Length, this);
2186 validateElement(XsdTagScope::LengthFacet);
2188 const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
2189 facet->setType(XsdFacet::Length);
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);
2200 facet->setFixed(fixed->as<Boolean>()->value());
2202 facet->setFixed(false); // the default value
2205 const QString value = readAttribute(QString::fromLatin1("value"));
2206 DerivedInteger<TypeNonNegativeInteger>::Ptr integer = DerivedInteger<TypeNonNegativeInteger>::fromLexical(m_namePool, value);
2207 if (integer->hasError()) {
2208 attributeContentError("value", "length", value, BuiltinTypes::xsNonNegativeInteger);
2211 facet->setValue(integer);
2214 validateIdAttribute("length");
2216 TagValidationHandler tagValidator(XsdTagScope::LengthFacet, this, m_namePool);
2224 if (isStartElement()) {
2225 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
2226 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
2228 tagValidator.validate(token);
2230 if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
2231 const XsdAnnotation::Ptr annotation = parseAnnotation();
2232 facet->addAnnotation(annotation);
2239 tagValidator.finalize();
2244 XsdFacet::Ptr XsdSchemaParser::parseMinLengthFacet()
2246 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::MinLength, this);
2248 validateElement(XsdTagScope::MinLengthFacet);
2250 const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
2251 facet->setType(XsdFacet::MinimumLength);
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);
2262 facet->setFixed(fixed->as<Boolean>()->value());
2264 facet->setFixed(false); // the default value
2267 const QString value = readAttribute(QString::fromLatin1("value"));
2268 DerivedInteger<TypeNonNegativeInteger>::Ptr integer = DerivedInteger<TypeNonNegativeInteger>::fromLexical(m_namePool, value);
2269 if (integer->hasError()) {
2270 attributeContentError("value", "minLength", value, BuiltinTypes::xsNonNegativeInteger);
2273 facet->setValue(integer);
2276 validateIdAttribute("minLength");
2278 TagValidationHandler tagValidator(XsdTagScope::MinLengthFacet, this, m_namePool);
2286 if (isStartElement()) {
2287 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
2288 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
2290 tagValidator.validate(token);
2292 if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
2293 const XsdAnnotation::Ptr annotation = parseAnnotation();
2294 facet->addAnnotation(annotation);
2301 tagValidator.finalize();
2306 XsdFacet::Ptr XsdSchemaParser::parseMaxLengthFacet()
2308 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::MaxLength, this);
2310 validateElement(XsdTagScope::MaxLengthFacet);
2312 const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
2313 facet->setType(XsdFacet::MaximumLength);
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);
2324 facet->setFixed(fixed->as<Boolean>()->value());
2326 facet->setFixed(false); // the default value
2329 const QString value = readAttribute(QString::fromLatin1("value"));
2330 DerivedInteger<TypeNonNegativeInteger>::Ptr integer = DerivedInteger<TypeNonNegativeInteger>::fromLexical(m_namePool, value);
2331 if (integer->hasError()) {
2332 attributeContentError("value", "maxLength", value, BuiltinTypes::xsNonNegativeInteger);
2335 facet->setValue(integer);
2338 validateIdAttribute("maxLength");
2340 TagValidationHandler tagValidator(XsdTagScope::MaxLengthFacet, this, m_namePool);
2348 if (isStartElement()) {
2349 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
2350 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
2352 tagValidator.validate(token);
2354 if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
2355 const XsdAnnotation::Ptr annotation = parseAnnotation();
2356 facet->addAnnotation(annotation);
2363 tagValidator.finalize();
2368 XsdFacet::Ptr XsdSchemaParser::parseEnumerationFacet()
2370 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Enumeration, this);
2372 validateElement(XsdTagScope::EnumerationFacet);
2374 const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
2375 facet->setType(XsdFacet::Enumeration);
2378 facet->setFixed(false); // not defined in schema, but can't hurt
2380 const QString value = readAttribute(QString::fromLatin1("value"));
2382 // as enumeration can have a value of type anySimpleType, we just read
2383 // the string here and store it for later intepretation
2384 DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(m_namePool, value);
2385 if (string->hasError()) {
2386 attributeContentError("value", "enumeration", value);
2389 AtomicValue::List multiValue;
2390 multiValue << string;
2391 facet->setMultiValue(multiValue);
2393 m_schemaResolver->addEnumerationFacetValue(string, m_namespaceSupport);
2395 validateIdAttribute("enumeration");
2397 TagValidationHandler tagValidator(XsdTagScope::EnumerationFacet, this, m_namePool);
2405 if (isStartElement()) {
2406 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
2407 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
2409 tagValidator.validate(token);
2411 if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
2412 const XsdAnnotation::Ptr annotation = parseAnnotation();
2413 facet->addAnnotation(annotation);
2420 tagValidator.finalize();
2425 XsdFacet::Ptr XsdSchemaParser::parseWhiteSpaceFacet()
2427 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::WhiteSpace, this);
2429 validateElement(XsdTagScope::WhiteSpaceFacet);
2431 const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
2432 facet->setType(XsdFacet::WhiteSpace);
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);
2443 facet->setFixed(fixed->as<Boolean>()->value());
2445 facet->setFixed(false); // the default value
2448 const QString value = readAttribute(QString::fromLatin1("value"));
2449 if (value != XsdSchemaToken::toString(XsdSchemaToken::Collapse) &&
2450 value != XsdSchemaToken::toString(XsdSchemaToken::Preserve) &&
2451 value != XsdSchemaToken::toString(XsdSchemaToken::Replace)) {
2452 attributeContentError("value", "whiteSpace", value);
2455 DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(m_namePool, value);
2456 if (string->hasError()) {
2457 attributeContentError("value", "whiteSpace", value);
2460 facet->setValue(string);
2464 validateIdAttribute("whiteSpace");
2466 TagValidationHandler tagValidator(XsdTagScope::WhiteSpaceFacet, this, m_namePool);
2474 if (isStartElement()) {
2475 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
2476 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
2478 tagValidator.validate(token);
2480 if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
2481 const XsdAnnotation::Ptr annotation = parseAnnotation();
2482 facet->addAnnotation(annotation);
2489 tagValidator.finalize();
2494 XsdFacet::Ptr XsdSchemaParser::parsePatternFacet()
2496 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Pattern, this);
2498 validateElement(XsdTagScope::PatternFacet);
2500 const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
2501 facet->setType(XsdFacet::Pattern);
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"));
2508 DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(m_namePool, value);
2509 if (string->hasError()) {
2510 attributeContentError("value", "pattern", value);
2513 AtomicValue::List multiValue;
2514 multiValue << string;
2515 facet->setMultiValue(multiValue);
2518 validateIdAttribute("pattern");
2520 TagValidationHandler tagValidator(XsdTagScope::PatternFacet, this, m_namePool);
2528 if (isStartElement()) {
2529 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
2530 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
2532 tagValidator.validate(token);
2534 if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
2535 const XsdAnnotation::Ptr annotation = parseAnnotation();
2536 facet->addAnnotation(annotation);
2543 tagValidator.finalize();
2548 XsdFacet::Ptr XsdSchemaParser::parseAssertionFacet()
2550 // this is just a wrapper function around the parseAssertion() method
2552 const XsdAssertion::Ptr assertion = parseAssertion(XsdSchemaToken::Assertion, XsdTagScope::Assertion);
2554 const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
2555 facet->setType(XsdFacet::Assertion);
2556 facet->setAssertions(XsdAssertion::List() << assertion);
2561 XsdComplexType::Ptr XsdSchemaParser::parseGlobalComplexType()
2563 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::ComplexType, this);
2565 validateElement(XsdTagScope::GlobalComplexType);
2567 bool hasTypeSpecified = false;
2568 bool hasComplexContent = false;
2570 const XsdComplexType::Ptr complexType(new XsdComplexType());
2573 if (hasAttribute(QString::fromLatin1("abstract"))) {
2574 const QString abstract = readAttribute(QString::fromLatin1("abstract"));
2576 const Boolean::Ptr value = Boolean::fromLexical(abstract);
2577 if (value->hasError()) {
2578 attributeContentError("abstract", "complexType", abstract, BuiltinTypes::xsBoolean);
2582 complexType->setIsAbstract(value->as<Boolean>()->value());
2584 complexType->setIsAbstract(false); // default value
2587 complexType->setProhibitedSubstitutions(readBlockingConstraintAttribute(NamedSchemaComponent::ExtensionConstraint | NamedSchemaComponent::RestrictionConstraint, "complexType"));
2588 complexType->setDerivationConstraints(readDerivationConstraintAttribute(SchemaType::ExtensionConstraint | SchemaType::RestrictionConstraint, "complexType"));
2590 const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("complexType"));
2591 complexType->setName(objectName);
2593 bool effectiveMixed = false;
2594 if (hasAttribute(QString::fromLatin1("mixed"))) {
2595 const QString mixed = readAttribute(QString::fromLatin1("mixed"));
2597 const Boolean::Ptr value = Boolean::fromLexical(mixed);
2598 if (value->hasError()) {
2599 attributeContentError("mixed", "complexType", mixed, BuiltinTypes::xsBoolean);
2603 effectiveMixed = value->as<Boolean>()->value();
2606 validateIdAttribute("complexType");
2608 TagValidationHandler tagValidator(XsdTagScope::GlobalComplexType, this, m_namePool);
2616 if (isStartElement()) {
2617 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
2618 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
2620 tagValidator.validate(token);
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")));
2634 parseSimpleContent(complexType);
2635 hasTypeSpecified = true;
2636 } else if (isSchemaTag(XsdSchemaToken::ComplexContent, token, namespaceToken)) {
2638 parseComplexContent(complexType, &mixed);
2639 hasTypeSpecified = true;
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);
2653 complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
2654 complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
2655 complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
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);
2663 complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
2664 complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
2665 complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
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);
2673 complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
2674 complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
2675 complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
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);
2683 complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
2684 complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
2685 complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
2686 hasComplexContent = true;
2687 } else if (isSchemaTag(XsdSchemaToken::Attribute, token, namespaceToken)) {
2688 const XsdAttributeUse::Ptr attributeUse = parseLocalAttribute(complexType);
2689 complexType->addAttributeUse(attributeUse);
2691 complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
2692 complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
2693 complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
2694 hasComplexContent = true;
2695 } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) {
2696 const XsdAttributeUse::Ptr attributeUse = parseReferredAttributeGroup();
2697 complexType->addAttributeUse(attributeUse);
2699 complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
2700 complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
2701 complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
2702 hasComplexContent = true;
2703 } else if (isSchemaTag(XsdSchemaToken::AnyAttribute, token, namespaceToken)) {
2704 const XsdWildcard::Ptr wildcard = parseAnyAttribute();
2705 complexType->setAttributeWildcard(wildcard);
2707 complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
2708 complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
2709 complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
2710 hasComplexContent = true;
2711 } else if (isSchemaTag(XsdSchemaToken::Assert, token, namespaceToken)) {
2712 const XsdAssertion::Ptr assertion = parseAssertion(XsdSchemaToken::Assert, XsdTagScope::Assert);
2713 complexType->addAssertion(assertion);
2720 tagValidator.finalize();
2722 if (!hasTypeSpecified) {
2723 complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
2724 complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
2725 hasComplexContent = true;
2728 if (hasComplexContent == true) {
2729 resolveComplexContentType(complexType, effectiveMixed);
2735 XsdComplexType::Ptr XsdSchemaParser::parseLocalComplexType()
2737 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::ComplexType, this);
2739 validateElement(XsdTagScope::LocalComplexType);
2741 bool hasTypeSpecified = false;
2742 bool hasComplexContent = true;
2744 const XsdComplexType::Ptr complexType(new XsdComplexType());
2745 complexType->setName(m_parserContext->createAnonymousName(m_targetNamespace));
2748 bool effectiveMixed = false;
2749 if (hasAttribute(QString::fromLatin1("mixed"))) {
2750 const QString mixed = readAttribute(QString::fromLatin1("mixed"));
2752 const Boolean::Ptr value = Boolean::fromLexical(mixed);
2753 if (value->hasError()) {
2754 attributeContentError("mixed", "complexType", mixed, BuiltinTypes::xsBoolean);
2758 effectiveMixed = value->as<Boolean>()->value();
2761 validateIdAttribute("complexType");
2763 TagValidationHandler tagValidator(XsdTagScope::LocalComplexType, this, m_namePool);
2771 if (isStartElement()) {
2772 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
2773 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
2775 tagValidator.validate(token);
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)) {
2785 parseComplexContent(complexType, &mixed);
2786 hasTypeSpecified = true;
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);
2800 complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
2801 complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
2802 complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
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);
2810 complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
2811 complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
2812 complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
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);
2820 complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
2821 complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
2822 complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
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);
2830 complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
2831 complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
2832 complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
2833 hasComplexContent = true;
2834 } else if (isSchemaTag(XsdSchemaToken::Attribute, token, namespaceToken)) {
2835 const XsdAttributeUse::Ptr attributeUse = parseLocalAttribute(complexType);
2836 complexType->addAttributeUse(attributeUse);
2838 complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
2839 complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
2840 complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
2841 hasComplexContent = true;
2842 } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) {
2843 const XsdAttributeUse::Ptr attributeUse = parseReferredAttributeGroup();
2844 complexType->addAttributeUse(attributeUse);
2846 complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
2847 complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
2848 complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
2849 hasComplexContent = true;
2850 } else if (isSchemaTag(XsdSchemaToken::AnyAttribute, token, namespaceToken)) {
2851 const XsdWildcard::Ptr wildcard = parseAnyAttribute();
2852 complexType->setAttributeWildcard(wildcard);
2854 complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
2855 complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
2856 complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
2857 hasComplexContent = true;
2858 } else if (isSchemaTag(XsdSchemaToken::Assert, token, namespaceToken)) {
2859 const XsdAssertion::Ptr assertion = parseAssertion(XsdSchemaToken::Assert, XsdTagScope::Assert);
2860 complexType->addAssertion(assertion);
2867 tagValidator.finalize();
2869 if (!hasTypeSpecified) {
2870 complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
2871 complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
2872 hasComplexContent = true;
2875 if (hasComplexContent == true) {
2876 resolveComplexContentType(complexType, effectiveMixed);
2882 void XsdSchemaParser::resolveComplexContentType(const XsdComplexType::Ptr &complexType, bool effectiveMixed)
2884 // @see http://www.w3.org/TR/xmlschema11-1/#dcl.ctd.ctcc.common
2887 // the effectiveMixed contains the effective mixed value
2890 bool hasEmptyContent = false;
2891 if (!complexType->contentType()->particle()) {
2892 hasEmptyContent = true; // 2.1.1
2894 if (complexType->contentType()->particle()->term()->isModelGroup()) {
2895 const XsdModelGroup::Ptr group = complexType->contentType()->particle()->term();
2896 if (group->compositor() == XsdModelGroup::SequenceCompositor || group->compositor() == XsdModelGroup::AllCompositor) {
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
2904 if ((complexType->contentType()->particle()->maximumOccursUnbounded() == false) && (complexType->contentType()->particle()->maximumOccurs() == 0))
2905 hasEmptyContent = true; // 2.1.4
2909 const XsdParticle::Ptr explicitContent = (hasEmptyContent ? XsdParticle::Ptr() : complexType->contentType()->particle());
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);
2915 void XsdSchemaParser::parseSimpleContent(const XsdComplexType::Ptr &complexType)
2917 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::SimpleContent, this);
2919 validateElement(XsdTagScope::SimpleContent);
2921 complexType->contentType()->setVariety(XsdComplexType::ContentType::Simple);
2924 validateIdAttribute("simpleContent");
2926 TagValidationHandler tagValidator(XsdTagScope::SimpleContent, this, m_namePool);
2934 if (isStartElement()) {
2935 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
2936 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
2938 tagValidator.validate(token);
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);
2953 tagValidator.finalize();
2956 void XsdSchemaParser::parseSimpleContentRestriction(const XsdComplexType::Ptr &complexType)
2958 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Restriction, this);
2960 validateElement(XsdTagScope::SimpleContentRestriction);
2962 complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
2965 const QString baseType = readQNameAttribute(QString::fromLatin1("base"), "restriction");
2967 convertName(baseType, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName
2969 validateIdAttribute("restriction");
2971 XsdFacet::Hash facets;
2972 QList<XsdFacet::Ptr> patternFacets;
2973 QList<XsdFacet::Ptr> enumerationFacets;
2974 QList<XsdFacet::Ptr> assertionFacets;
2976 TagValidationHandler tagValidator(XsdTagScope::SimpleContentRestriction, this, m_namePool);
2984 if (isStartElement()) {
2985 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
2986 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
2988 tagValidator.validate(token);
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)) {
2994 const XsdSimpleType::Ptr type = parseLocalSimpleType();
2995 type->setContext(complexType); //TODO: investigate what the schema spec really wants here?!?
2996 complexType->contentType()->setSimpleType(type);
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)) {
3049 const XsdAssertion::Ptr assertion = parseAssertion(XsdSchemaToken::Assert, XsdTagScope::Assert);
3050 complexType->addAssertion(assertion);
3057 tagValidator.finalize();
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);
3064 AtomicValue::List multiValue;
3065 for (int i = 0; i < patternFacets.count(); ++i)
3066 multiValue << patternFacets.at(i)->multiValue();
3068 patternFacet->setMultiValue(multiValue);
3069 addFacet(patternFacet, facets, complexType);
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);
3077 AtomicValue::List multiValue;
3078 for (int i = 0; i < enumerationFacets.count(); ++i)
3079 multiValue << enumerationFacets.at(i)->multiValue();
3081 enumerationFacet->setMultiValue(multiValue);
3082 addFacet(enumerationFacet, facets, complexType);
3085 // merge all assertion facets into one facet
3086 if (!assertionFacets.isEmpty()) {
3087 const XsdFacet::Ptr assertionFacet(new XsdFacet());
3088 assertionFacet->setType(XsdFacet::Assertion);
3090 XsdAssertion::List assertions;
3091 for (int i = 0; i < assertionFacets.count(); ++i)
3092 assertions << assertionFacets.at(i)->assertions();
3094 assertionFacet->setAssertions(assertions);
3095 addFacet(assertionFacet, facets, complexType);
3098 m_schemaResolver->addComplexBaseType(complexType, typeName, currentSourceLocation(), facets); // add to resolver
3101 void XsdSchemaParser::parseSimpleContentExtension(const XsdComplexType::Ptr &complexType)
3103 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Extension, this);
3105 validateElement(XsdTagScope::SimpleContentExtension);
3107 complexType->setDerivationMethod(XsdComplexType::DerivationExtension);
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
3115 validateIdAttribute("extension");
3117 TagValidationHandler tagValidator(XsdTagScope::SimpleContentExtension, this, m_namePool);
3125 if (isStartElement()) {
3126 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
3127 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
3129 tagValidator.validate(token);
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)) {
3144 const XsdAssertion::Ptr assertion = parseAssertion(XsdSchemaToken::Assert, XsdTagScope::Assert);
3145 complexType->addAssertion(assertion);
3152 tagValidator.finalize();
3155 void XsdSchemaParser::parseComplexContent(const XsdComplexType::Ptr &complexType, bool *mixed)
3157 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::ComplexContent, this);
3159 validateElement(XsdTagScope::ComplexContent);
3161 complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
3164 if (hasAttribute(QString::fromLatin1("mixed"))) {
3165 const QString mixedStr = readAttribute(QString::fromLatin1("mixed"));
3167 const Boolean::Ptr value = Boolean::fromLexical(mixedStr);
3168 if (value->hasError()) {
3169 attributeContentError("mixed", "complexType", mixedStr, BuiltinTypes::xsBoolean);
3173 *mixed = value->as<Boolean>()->value();
3178 validateIdAttribute("complexContent");
3180 TagValidationHandler tagValidator(XsdTagScope::ComplexContent, this, m_namePool);
3188 if (isStartElement()) {
3189 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
3190 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
3192 tagValidator.validate(token);
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);
3207 tagValidator.finalize();
3210 void XsdSchemaParser::parseComplexContentRestriction(const XsdComplexType::Ptr &complexType)
3212 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Restriction, this);
3214 validateElement(XsdTagScope::ComplexContentRestriction);
3216 complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
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
3224 validateIdAttribute("restriction");
3226 TagValidationHandler tagValidator(XsdTagScope::ComplexContentRestriction, this, m_namePool);
3228 bool hasContent = false;
3235 if (isStartElement()) {
3236 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
3237 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
3239 tagValidator.validate(token);
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);
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);
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);
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);
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);
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)) {
3282 const XsdAssertion::Ptr assertion = parseAssertion(XsdSchemaToken::Assert, XsdTagScope::Assert);
3283 complexType->addAssertion(assertion);
3291 complexType->contentType()->setVariety(XsdComplexType::ContentType::Empty);
3293 tagValidator.finalize();
3296 void XsdSchemaParser::parseComplexContentExtension(const XsdComplexType::Ptr &complexType)
3298 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Extension, this);
3300 validateElement(XsdTagScope::ComplexContentExtension);
3302 complexType->setDerivationMethod(XsdComplexType::DerivationExtension);
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
3310 validateIdAttribute("extension");
3312 TagValidationHandler tagValidator(XsdTagScope::ComplexContentExtension, this, m_namePool);
3314 bool hasContent = false;
3321 if (isStartElement()) {
3322 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
3323 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
3325 tagValidator.validate(token);
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);
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);
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);
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);
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);
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)) {
3368 const XsdAssertion::Ptr assertion = parseAssertion(XsdSchemaToken::Assert, XsdTagScope::Assert);
3369 complexType->addAssertion(assertion);
3377 complexType->contentType()->setVariety(XsdComplexType::ContentType::Empty);
3379 tagValidator.finalize();
3383 XsdAssertion::Ptr XsdSchemaParser::parseAssertion(const XsdSchemaToken::NodeName &nodeName, const XsdTagScope::Type &tag)
3385 const ElementNamespaceHandler namespaceHandler(nodeName, this);
3387 validateElement(tag);
3389 const XsdAssertion::Ptr assertion(new XsdAssertion());
3393 const XsdXPathExpression::Ptr expression = readXPathExpression("assertion");
3394 assertion->setTest(expression);
3396 const QString test = readXPathAttribute(QString::fromLatin1("test"), XPath20, "assertion");
3397 expression->setExpression(test);
3399 validateIdAttribute("assertion");
3401 TagValidationHandler tagValidator(tag, this, m_namePool);
3409 if (isStartElement()) {
3410 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
3411 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
3413 tagValidator.validate(token);
3415 if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
3416 const XsdAnnotation::Ptr annotation = parseAnnotation();
3417 assertion->addAnnotation(annotation);
3424 tagValidator.finalize();
3429 XsdComplexType::OpenContent::Ptr XsdSchemaParser::parseOpenContent()
3431 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::OpenContent, this);
3433 validateElement(XsdTagScope::OpenContent);
3435 const XsdComplexType::OpenContent::Ptr openContent(new XsdComplexType::OpenContent());
3437 if (hasAttribute(QString::fromLatin1("mode"))) {
3438 const QString mode = readAttribute(QString::fromLatin1("mode"));
3440 if (mode == QString::fromLatin1("none")) {
3441 m_defaultOpenContent->setMode(XsdComplexType::OpenContent::None);
3442 } else if (mode == QString::fromLatin1("interleave")) {
3443 m_defaultOpenContent->setMode(XsdComplexType::OpenContent::Interleave);
3444 } else if (mode == QString::fromLatin1("suffix")) {
3445 m_defaultOpenContent->setMode(XsdComplexType::OpenContent::Suffix);
3447 attributeContentError("mode", "openContent", mode);
3451 openContent->setMode(XsdComplexType::OpenContent::Interleave);
3454 validateIdAttribute("openContent");
3456 TagValidationHandler tagValidator(XsdTagScope::OpenContent, this, m_namePool);
3464 if (isStartElement()) {
3465 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
3466 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
3468 tagValidator.validate(token);
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);
3483 tagValidator.finalize();
3488 XsdModelGroup::Ptr XsdSchemaParser::parseNamedGroup()
3490 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Group, this);
3492 validateElement(XsdTagScope::NamedGroup);
3494 const XsdModelGroup::Ptr modelGroup(new XsdModelGroup());
3495 XsdModelGroup::Ptr group;
3497 QXmlName objectName;
3498 if (hasAttribute(QString::fromLatin1("name"))) {
3499 objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("group"));
3502 validateIdAttribute("group");
3504 TagValidationHandler tagValidator(XsdTagScope::NamedGroup, this, m_namePool);
3506 XsdAnnotation::Ptr annotation;
3514 if (isStartElement()) {
3515 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
3516 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
3518 tagValidator.validate(token);
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);
3534 tagValidator.finalize();
3536 group->setName(objectName);
3539 group->addAnnotation(annotation);
3544 XsdTerm::Ptr XsdSchemaParser::parseReferredGroup(const XsdParticle::Ptr &particle)
3546 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Group, this);
3548 validateElement(XsdTagScope::ReferredGroup);
3550 const XsdReference::Ptr reference(new XsdReference());
3551 reference->setType(XsdReference::ModelGroup);
3552 reference->setSourceLocation(currentSourceLocation());
3555 if (!parseMinMaxConstraint(particle, "group")) {
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);
3564 validateIdAttribute("group");
3566 TagValidationHandler tagValidator(XsdTagScope::ReferredGroup, this, m_namePool);
3574 if (isStartElement()) {
3575 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
3576 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
3578 tagValidator.validate(token);
3580 if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
3581 const XsdAnnotation::Ptr annotation = parseAnnotation();
3582 reference->addAnnotation(annotation);
3589 tagValidator.finalize();
3594 XsdModelGroup::Ptr XsdSchemaParser::parseAll(const NamedSchemaComponent::Ptr &parent)
3596 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::All, this);
3598 validateElement(XsdTagScope::All);
3600 const XsdModelGroup::Ptr modelGroup(new XsdModelGroup());
3601 modelGroup->setCompositor(XsdModelGroup::AllCompositor);
3603 validateIdAttribute("all");
3605 TagValidationHandler tagValidator(XsdTagScope::All, this, m_namePool);
3607 XsdParticle::List particles;
3614 if (isStartElement()) {
3615 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
3616 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
3618 tagValidator.validate(token);
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);
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")));
3637 particles.append(particle);
3644 modelGroup->setParticles(particles);
3646 tagValidator.finalize();
3651 XsdModelGroup::Ptr XsdSchemaParser::parseLocalAll(const XsdParticle::Ptr &particle, const NamedSchemaComponent::Ptr &parent)
3653 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::All, this);
3655 validateElement(XsdTagScope::LocalAll);
3657 const XsdModelGroup::Ptr modelGroup(new XsdModelGroup());
3658 modelGroup->setCompositor(XsdModelGroup::AllCompositor);
3661 if (!parseMinMaxConstraint(particle, "all")) {
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")));
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")));
3680 validateIdAttribute("all");
3682 TagValidationHandler tagValidator(XsdTagScope::LocalAll, this, m_namePool);
3684 XsdParticle::List particles;
3691 if (isStartElement()) {
3692 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
3693 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
3695 tagValidator.validate(token);
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);
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")));
3714 particles.append(particle);
3721 modelGroup->setParticles(particles);
3723 tagValidator.finalize();
3728 XsdModelGroup::Ptr XsdSchemaParser::parseChoice(const NamedSchemaComponent::Ptr &parent)
3730 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Choice, this);
3732 validateElement(XsdTagScope::Choice);
3734 const XsdModelGroup::Ptr modelGroup(new XsdModelGroup());
3735 modelGroup->setCompositor(XsdModelGroup::ChoiceCompositor);
3737 validateIdAttribute("choice");
3739 XsdParticle::List particles;
3741 TagValidationHandler tagValidator(XsdTagScope::Choice, this, m_namePool);
3749 if (isStartElement()) {
3750 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
3751 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
3753 tagValidator.validate(token);
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);
3766 m_schemaResolver->addAllGroupCheck(term);
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);
3790 modelGroup->setParticles(particles);
3792 tagValidator.finalize();
3797 XsdModelGroup::Ptr XsdSchemaParser::parseLocalChoice(const XsdParticle::Ptr &particle, const NamedSchemaComponent::Ptr &parent)
3799 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Choice, this);
3801 validateElement(XsdTagScope::LocalChoice);
3803 const XsdModelGroup::Ptr modelGroup(new XsdModelGroup());
3804 modelGroup->setCompositor(XsdModelGroup::ChoiceCompositor);
3807 if (!parseMinMaxConstraint(particle, "choice")) {
3811 validateIdAttribute("choice");
3813 XsdParticle::List particles;
3815 TagValidationHandler tagValidator(XsdTagScope::LocalChoice, this, m_namePool);
3823 if (isStartElement()) {
3824 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
3825 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
3827 tagValidator.validate(token);
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);
3840 m_schemaResolver->addAllGroupCheck(term);
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);
3864 modelGroup->setParticles(particles);
3866 tagValidator.finalize();
3871 XsdModelGroup::Ptr XsdSchemaParser::parseSequence(const NamedSchemaComponent::Ptr &parent)
3873 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Sequence, this);
3875 validateElement(XsdTagScope::Sequence);
3877 const XsdModelGroup::Ptr modelGroup(new XsdModelGroup());
3878 modelGroup->setCompositor(XsdModelGroup::SequenceCompositor);
3880 validateIdAttribute("sequence");
3882 XsdParticle::List particles;
3884 TagValidationHandler tagValidator(XsdTagScope::Sequence, this, m_namePool);
3892 if (isStartElement()) {
3893 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
3894 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
3896 tagValidator.validate(token);
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);
3909 m_schemaResolver->addAllGroupCheck(term);
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);
3933 modelGroup->setParticles(particles);
3935 tagValidator.finalize();
3940 XsdModelGroup::Ptr XsdSchemaParser::parseLocalSequence(const XsdParticle::Ptr &particle, const NamedSchemaComponent::Ptr &parent)
3942 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Sequence, this);
3944 validateElement(XsdTagScope::LocalSequence);
3946 const XsdModelGroup::Ptr modelGroup(new XsdModelGroup());
3947 modelGroup->setCompositor(XsdModelGroup::SequenceCompositor);
3950 if (!parseMinMaxConstraint(particle, "sequence")) {
3954 validateIdAttribute("sequence");
3956 XsdParticle::List particles;
3958 TagValidationHandler tagValidator(XsdTagScope::LocalSequence, this, m_namePool);
3966 if (isStartElement()) {
3967 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
3968 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
3970 tagValidator.validate(token);
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);
3983 m_schemaResolver->addAllGroupCheck(term);
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);
4007 modelGroup->setParticles(particles);
4009 tagValidator.finalize();
4014 XsdAttribute::Ptr XsdSchemaParser::parseGlobalAttribute()
4016 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Attribute, this);
4018 validateElement(XsdTagScope::GlobalAttribute);
4020 const XsdAttribute::Ptr attribute(new XsdAttribute());
4021 attribute->setScope(XsdAttribute::Scope::Ptr(new XsdAttribute::Scope()));
4022 attribute->scope()->setVariety(XsdAttribute::Scope::Global);
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")));
4033 if (hasAttribute(QString::fromLatin1("default"))) {
4034 const QString value = readAttribute(QString::fromLatin1("default"));
4035 attribute->setValueConstraint(XsdAttribute::ValueConstraint::Ptr(new XsdAttribute::ValueConstraint()));
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"));
4040 attribute->setValueConstraint(XsdAttribute::ValueConstraint::Ptr(new XsdAttribute::ValueConstraint()));
4041 attribute->valueConstraint()->setVariety(XsdAttribute::ValueConstraint::Fixed);
4042 attribute->valueConstraint()->setValue(value);
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"))) {
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"))
4055 .arg(formatURI(CommonNamespaces::XSI)));
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")));
4065 attribute->setName(objectName);
4067 bool hasTypeAttribute = false;
4068 bool hasTypeSpecified = false;
4070 if (hasAttribute(QString::fromLatin1("type"))) {
4071 hasTypeAttribute = true;
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;
4080 validateIdAttribute("attribute");
4082 TagValidationHandler tagValidator(XsdTagScope::GlobalAttribute, this, m_namePool);
4090 if (isStartElement()) {
4091 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
4092 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
4094 tagValidator.validate(token);
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")));
4108 const XsdSimpleType::Ptr type = parseLocalSimpleType();
4109 type->setContext(attribute);
4110 attribute->setType(type);
4111 hasTypeSpecified = true;
4113 // add it to list of anonymous types as well
4114 addAnonymousType(type);
4121 if (!hasTypeSpecified) {
4122 attribute->setType(BuiltinTypes::xsAnySimpleType); // default value
4126 tagValidator.finalize();
4131 XsdAttributeUse::Ptr XsdSchemaParser::parseLocalAttribute(const NamedSchemaComponent::Ptr &parent)
4133 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Attribute, this);
4135 validateElement(XsdTagScope::LocalAttribute);
4137 bool hasRefAttribute = false;
4138 bool hasTypeAttribute = false;
4139 bool hasTypeSpecified = false;
4141 XsdAttributeUse::Ptr attributeUse;
4142 if (hasAttribute(QString::fromLatin1("ref"))) {
4143 const XsdAttributeReference::Ptr reference = XsdAttributeReference::Ptr(new XsdAttributeReference());
4144 reference->setType(XsdAttributeReference::AttributeUse);
4145 reference->setSourceLocation(currentSourceLocation());
4147 attributeUse = reference;
4148 hasRefAttribute = true;
4150 attributeUse = XsdAttributeUse::Ptr(new XsdAttributeUse());
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;
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;
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;
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;
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);
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;
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);
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;
4226 const XsdAttribute::Ptr attribute(new XsdAttribute());
4228 attributeUse->setAttribute(attribute);
4229 m_componentLocationHash.insert(attribute, currentSourceLocation());
4231 attribute->setScope(XsdAttribute::Scope::Ptr(new XsdAttribute::Scope()));
4232 attribute->scope()->setVariety(XsdAttribute::Scope::Local);
4233 attribute->scope()->setParent(parent);
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
4241 const XsdAttributeReference::Ptr attributeReference = attributeUse;
4242 attributeReference->setReferenceName(referenceName);
4244 if (hasAttribute(QString::fromLatin1("name"))) {
4245 const QString attributeName = readNameAttribute("attribute");
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;
4255 if (value == QString::fromLatin1("qualified")) {
4256 objectName = m_namePool->allocateQName(m_targetNamespace, attributeName);
4258 objectName = m_namePool->allocateQName(QString(), attributeName);
4261 if (m_attributeFormDefault == QString::fromLatin1("qualified")) {
4262 objectName = m_namePool->allocateQName(m_targetNamespace, attributeName);
4264 objectName = m_namePool->allocateQName(QString(), attributeName);
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"))) {
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"))
4277 .arg(formatURI(CommonNamespaces::XSI)));
4278 return attributeUse;
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;
4288 attribute->setName(objectName);
4291 if (hasAttribute(QString::fromLatin1("type"))) {
4292 hasTypeAttribute = true;
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;
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())
4304 attribute->setValueConstraint(XsdAttribute::ValueConstraint::Ptr(new XsdAttribute::ValueConstraint()));
4306 attribute->valueConstraint()->setVariety((XsdAttribute::ValueConstraint::Variety)attributeUse->valueConstraint()->variety());
4307 attribute->valueConstraint()->setValue(attributeUse->valueConstraint()->value());
4308 attribute->valueConstraint()->setLexicalForm(attributeUse->valueConstraint()->lexicalForm());
4312 validateIdAttribute("attribute");
4314 TagValidationHandler tagValidator(XsdTagScope::LocalAttribute, this, m_namePool);
4322 if (isStartElement()) {
4323 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
4324 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
4326 tagValidator.validate(token);
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")));
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")));
4347 const XsdSimpleType::Ptr type = parseLocalSimpleType();
4348 type->setContext(attribute);
4349 attribute->setType(type);
4350 hasTypeSpecified = true;
4352 // add it to list of anonymous types as well
4353 addAnonymousType(type);
4360 if (!hasTypeSpecified) {
4361 attribute->setType(BuiltinTypes::xsAnySimpleType); // default value
4364 tagValidator.finalize();
4366 return attributeUse;
4369 XsdAttributeGroup::Ptr XsdSchemaParser::parseNamedAttributeGroup()
4371 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::AttributeGroup, this);
4373 validateElement(XsdTagScope::NamedAttributeGroup);
4375 const XsdAttributeGroup::Ptr attributeGroup(new XsdAttributeGroup());
4378 const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("attributeGroup"));
4379 attributeGroup->setName(objectName);
4381 validateIdAttribute("attributeGroup");
4383 TagValidationHandler tagValidator(XsdTagScope::NamedAttributeGroup, this, m_namePool);
4391 if (isStartElement()) {
4392 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
4393 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
4395 tagValidator.validate(token);
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);
4403 if (attributeUse->useType() == XsdAttributeUse::ProhibitedUse) {
4404 warning(QtXmlPatterns::tr("Specifying use='prohibited' inside an attribute group has no effect."));
4406 attributeGroup->addAttributeUse(attributeUse);
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);
4420 tagValidator.finalize();
4422 return attributeGroup;
4425 XsdAttributeUse::Ptr XsdSchemaParser::parseReferredAttributeGroup()
4427 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::AttributeGroup, this);
4429 validateElement(XsdTagScope::ReferredAttributeGroup);
4431 const XsdAttributeReference::Ptr attributeReference(new XsdAttributeReference());
4432 attributeReference->setType(XsdAttributeReference::AttributeGroup);
4433 attributeReference->setSourceLocation(currentSourceLocation());
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);
4441 validateIdAttribute("attributeGroup");
4443 TagValidationHandler tagValidator(XsdTagScope::ReferredAttributeGroup, this, m_namePool);
4451 if (isStartElement()) {
4452 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
4453 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
4455 tagValidator.validate(token);
4457 if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
4458 const XsdAnnotation::Ptr annotation = parseAnnotation();
4459 attributeReference->addAnnotation(annotation);
4466 tagValidator.finalize();
4468 return attributeReference;
4471 XsdElement::Ptr XsdSchemaParser::parseGlobalElement()
4473 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Element, this);
4475 validateElement(XsdTagScope::GlobalElement);
4477 const XsdElement::Ptr element(new XsdElement());
4478 element->setScope(XsdElement::Scope::Ptr(new XsdElement::Scope()));
4479 element->scope()->setVariety(XsdElement::Scope::Global);
4481 bool hasTypeAttribute = false;
4482 bool hasTypeSpecified = false;
4483 bool hasSubstitutionGroup = false;
4486 const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("element"));
4487 element->setName(objectName);
4489 if (hasAttribute(QString::fromLatin1("abstract"))) {
4490 const QString abstract = readAttribute(QString::fromLatin1("abstract"));
4492 const Boolean::Ptr value = Boolean::fromLexical(abstract);
4493 if (value->hasError()) {
4494 attributeContentError("abstract", "element", abstract, BuiltinTypes::xsBoolean);
4498 element->setIsAbstract(value->as<Boolean>()->value());
4500 element->setIsAbstract(false); // the default value
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")));
4511 if (hasAttribute(QString::fromLatin1("default"))) {
4512 const QString value = readAttribute(QString::fromLatin1("default"));
4513 element->setValueConstraint(XsdElement::ValueConstraint::Ptr(new XsdElement::ValueConstraint()));
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"));
4518 element->setValueConstraint(XsdElement::ValueConstraint::Ptr(new XsdElement::ValueConstraint()));
4519 element->valueConstraint()->setVariety(XsdElement::ValueConstraint::Fixed);
4520 element->valueConstraint()->setValue(value);
4523 element->setDisallowedSubstitutions(readBlockingConstraintAttribute(NamedSchemaComponent::ExtensionConstraint | NamedSchemaComponent::RestrictionConstraint | NamedSchemaComponent::SubstitutionConstraint, "element"));
4524 element->setSubstitutionGroupExclusions(readDerivationConstraintAttribute(SchemaType::ExtensionConstraint | SchemaType::RestrictionConstraint, "element"));
4526 if (hasAttribute(QString::fromLatin1("nillable"))) {
4527 const QString nillable = readAttribute(QString::fromLatin1("nillable"));
4529 const Boolean::Ptr value = Boolean::fromLexical(nillable);
4530 if (value->hasError()) {
4531 attributeContentError("nillable", "element", nillable, BuiltinTypes::xsBoolean);
4535 element->setIsNillable(value->as<Boolean>()->value());
4537 element->setIsNillable(false); // the default value
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
4546 hasTypeAttribute = true;
4547 hasTypeSpecified = true;
4550 if (hasAttribute(QString::fromLatin1("substitutionGroup"))) {
4551 QList<QXmlName> elementNames;
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);
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);
4567 QXmlName elementName;
4568 convertName(value, NamespaceSupport::ElementName, elementName); // translate qualified name into QXmlName
4569 elementNames.append(elementName);
4572 m_schemaResolver->addSubstitutionGroupAffiliation(element, elementNames, currentSourceLocation()); // add to resolver
4574 hasSubstitutionGroup = true;
4577 validateIdAttribute("element");
4579 XsdAlternative::List alternatives;
4581 TagValidationHandler tagValidator(XsdTagScope::GlobalElement, this, m_namePool);
4589 if (isStartElement()) {
4590 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
4591 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
4593 tagValidator.validate(token);
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")));
4607 const XsdSimpleType::Ptr type = parseLocalSimpleType();
4608 type->setContext(element);
4609 element->setType(type);
4611 // add it to list of anonymous types as well
4612 addAnonymousType(type);
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")));
4624 const XsdComplexType::Ptr type = parseLocalComplexType();
4625 type->setContext(element);
4626 element->setType(type);
4628 // add it to list of anonymous types as well
4629 addAnonymousType(type);
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);
4650 tagValidator.finalize();
4652 if (!hasTypeSpecified) {
4653 if (hasSubstitutionGroup)
4654 m_schemaResolver->addSubstitutionGroupType(element);
4656 element->setType(BuiltinTypes::xsAnyType);
4659 if (!alternatives.isEmpty()) {
4660 element->setTypeTable(XsdElement::TypeTable::Ptr(new XsdElement::TypeTable()));
4662 for (int i = 0; i < alternatives.count(); ++i) {
4663 if (alternatives.at(i)->test())
4664 element->typeTable()->addAlternative(alternatives.at(i));
4666 if (i == (alternatives.count() - 1)) { // the final one
4667 if (!alternatives.at(i)->test()) {
4668 element->typeTable()->setDefaultTypeDefinition(alternatives.at(i));
4670 const XsdAlternative::Ptr alternative(new XsdAlternative());
4671 if (element->type())
4672 alternative->setType(element->type());
4674 m_schemaResolver->addAlternativeType(alternative, element); // add to resolver
4676 element->typeTable()->setDefaultTypeDefinition(alternative);
4685 XsdTerm::Ptr XsdSchemaParser::parseLocalElement(const XsdParticle::Ptr &particle, const NamedSchemaComponent::Ptr &parent)
4687 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Element, this);
4689 validateElement(XsdTagScope::LocalElement);
4691 bool hasRefAttribute = false;
4692 bool hasTypeAttribute = false;
4693 bool hasTypeSpecified = false;
4696 XsdElement::Ptr element;
4697 if (hasAttribute(QString::fromLatin1("ref"))) {
4698 term = XsdReference::Ptr(new XsdReference());
4699 hasRefAttribute = true;
4701 term = XsdElement::Ptr(new XsdElement());
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")));
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")));
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")));
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")));
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")));
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")));
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")));
4752 if (!parseMinMaxConstraint(particle, "element")) {
4756 if (!hasAttribute(QString::fromLatin1("name")) && !hasAttribute(QString::fromLatin1("ref"))) {
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")));
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
4769 const XsdReference::Ptr reference = term;
4770 reference->setReferenceName(referenceName);
4771 reference->setType(XsdReference::Element);
4772 reference->setSourceLocation(currentSourceLocation());
4774 element->setScope(XsdElement::Scope::Ptr(new XsdElement::Scope()));
4775 element->scope()->setVariety(XsdElement::Scope::Local);
4776 element->scope()->setParent(parent);
4778 if (hasAttribute(QString::fromLatin1("name"))) {
4779 const QString elementName = readNameAttribute("element");
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);
4789 if (value == QString::fromLatin1("qualified")) {
4790 objectName = m_namePool->allocateQName(m_targetNamespace, elementName);
4792 objectName = m_namePool->allocateQName(QString(), elementName);
4795 if (m_elementFormDefault == QString::fromLatin1("qualified")) {
4796 objectName = m_namePool->allocateQName(m_targetNamespace, elementName);
4798 objectName = m_namePool->allocateQName(QString(), elementName);
4802 element->setName(objectName);
4805 if (hasAttribute(QString::fromLatin1("nillable"))) {
4806 const QString nillable = readAttribute(QString::fromLatin1("nillable"));
4808 const Boolean::Ptr value = Boolean::fromLexical(nillable);
4809 if (value->hasError()) {
4810 attributeContentError("nillable", "element", nillable, BuiltinTypes::xsBoolean);
4814 element->setIsNillable(value->as<Boolean>()->value());
4816 element->setIsNillable(false); // the default value
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")));
4827 if (hasAttribute(QString::fromLatin1("default"))) {
4828 const QString value = readAttribute(QString::fromLatin1("default"));
4829 element->setValueConstraint(XsdElement::ValueConstraint::Ptr(new XsdElement::ValueConstraint()));
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"));
4834 element->setValueConstraint(XsdElement::ValueConstraint::Ptr(new XsdElement::ValueConstraint()));
4835 element->valueConstraint()->setVariety(XsdElement::ValueConstraint::Fixed);
4836 element->valueConstraint()->setValue(value);
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
4845 hasTypeAttribute = true;
4846 hasTypeSpecified = true;
4849 element->setDisallowedSubstitutions(readBlockingConstraintAttribute(NamedSchemaComponent::ExtensionConstraint | NamedSchemaComponent::RestrictionConstraint | NamedSchemaComponent::SubstitutionConstraint, "element"));
4852 validateIdAttribute("element");
4854 XsdAlternative::List alternatives;
4856 TagValidationHandler tagValidator(XsdTagScope::LocalElement, this, m_namePool);
4864 if (isStartElement()) {
4865 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
4866 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
4868 tagValidator.validate(token);
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")));
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")));
4888 const XsdSimpleType::Ptr type = parseLocalSimpleType();
4889 type->setContext(element);
4890 element->setType(type);
4892 // add it to list of anonymous types as well
4893 addAnonymousType(type);
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")));
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")));
4911 const XsdComplexType::Ptr type = parseLocalComplexType();
4912 type->setContext(element);
4913 element->setType(type);
4915 // add it to list of anonymous types as well
4916 addAnonymousType(type);
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")));
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")));
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")));
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")));
4961 const XsdIdentityConstraint::Ptr constraint = parseKeyRef(element);
4962 element->addIdentityConstraint(constraint);
4969 tagValidator.finalize();
4971 if (!hasTypeSpecified && !hasRefAttribute)
4972 element->setType(BuiltinTypes::xsAnyType);
4974 if (!hasRefAttribute && !alternatives.isEmpty()) {
4975 element->setTypeTable(XsdElement::TypeTable::Ptr(new XsdElement::TypeTable()));
4977 for (int i = 0; i < alternatives.count(); ++i) {
4978 if (alternatives.at(i)->test())
4979 element->typeTable()->addAlternative(alternatives.at(i));
4981 if (i == (alternatives.count() - 1)) { // the final one
4982 if (!alternatives.at(i)->test()) {
4983 element->typeTable()->setDefaultTypeDefinition(alternatives.at(i));
4985 const XsdAlternative::Ptr alternative(new XsdAlternative());
4986 if (element->type())
4987 alternative->setType(element->type());
4989 m_schemaResolver->addAlternativeType(alternative, element); // add to resolver
4991 element->typeTable()->setDefaultTypeDefinition(alternative);
5000 XsdIdentityConstraint::Ptr XsdSchemaParser::parseUnique()
5002 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Unique, this);
5004 validateElement(XsdTagScope::Unique);
5006 const XsdIdentityConstraint::Ptr constraint(new XsdIdentityConstraint());
5007 constraint->setCategory(XsdIdentityConstraint::Unique);
5010 const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("unique"));
5011 constraint->setName(objectName);
5013 validateIdAttribute("unique");
5015 TagValidationHandler tagValidator(XsdTagScope::Unique, this, m_namePool);
5023 if (isStartElement()) {
5024 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
5025 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
5027 tagValidator.validate(token);
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);
5042 // add constraint to schema for further checking
5043 addIdentityConstraint(constraint);
5045 tagValidator.finalize();
5050 XsdIdentityConstraint::Ptr XsdSchemaParser::parseKey()
5052 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Key, this);
5054 validateElement(XsdTagScope::Key);
5056 const XsdIdentityConstraint::Ptr constraint(new XsdIdentityConstraint());
5057 constraint->setCategory(XsdIdentityConstraint::Key);
5060 const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("key"));
5061 constraint->setName(objectName);
5063 validateIdAttribute("key");
5065 TagValidationHandler tagValidator(XsdTagScope::Key, this, m_namePool);
5073 if (isStartElement()) {
5074 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
5075 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
5077 tagValidator.validate(token);
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);
5092 // add constraint to schema for further checking
5093 addIdentityConstraint(constraint);
5095 tagValidator.finalize();
5100 XsdIdentityConstraint::Ptr XsdSchemaParser::parseKeyRef(const XsdElement::Ptr &element)
5102 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Keyref, this);
5104 validateElement(XsdTagScope::KeyRef);
5106 const XsdIdentityConstraint::Ptr constraint(new XsdIdentityConstraint());
5107 constraint->setCategory(XsdIdentityConstraint::KeyReference);
5110 const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("keyref"));
5111 constraint->setName(objectName);
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
5118 validateIdAttribute("keyref");
5120 TagValidationHandler tagValidator(XsdTagScope::KeyRef, this, m_namePool);
5128 if (isStartElement()) {
5129 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
5130 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
5132 tagValidator.validate(token);
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);
5147 // add constraint to schema for further checking
5148 addIdentityConstraint(constraint);
5150 tagValidator.finalize();
5155 void XsdSchemaParser::parseSelector(const XsdIdentityConstraint::Ptr &ptr)
5157 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Selector, this);
5159 validateElement(XsdTagScope::Selector);
5162 const XsdXPathExpression::Ptr expression = readXPathExpression("selector");
5164 const QString xpath = readXPathAttribute(QString::fromLatin1("xpath"), XPathSelector, "selector");
5165 expression->setExpression(xpath);
5167 ptr->setSelector(expression);
5169 validateIdAttribute("selector");
5171 TagValidationHandler tagValidator(XsdTagScope::Selector, this, m_namePool);
5179 if (isStartElement()) {
5180 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
5181 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
5183 tagValidator.validate(token);
5185 if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
5186 const XsdAnnotation::Ptr annotation = parseAnnotation();
5187 expression->addAnnotation(annotation);
5194 tagValidator.finalize();
5197 void XsdSchemaParser::parseField(const XsdIdentityConstraint::Ptr &ptr)
5199 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Field, this);
5201 validateElement(XsdTagScope::Field);
5204 const XsdXPathExpression::Ptr expression = readXPathExpression("field");
5206 const QString xpath = readXPathAttribute(QString::fromLatin1("xpath"), XPathField, "field");
5207 expression->setExpression(xpath);
5209 ptr->addField(expression);
5211 validateIdAttribute("field");
5213 TagValidationHandler tagValidator(XsdTagScope::Field, this, m_namePool);
5221 if (isStartElement()) {
5222 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
5223 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
5225 tagValidator.validate(token);
5227 if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
5228 const XsdAnnotation::Ptr annotation = parseAnnotation();
5229 expression->addAnnotation(annotation);
5236 tagValidator.finalize();
5239 XsdAlternative::Ptr XsdSchemaParser::parseAlternative()
5241 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Alternative, this);
5243 validateElement(XsdTagScope::Alternative);
5245 const XsdAlternative::Ptr alternative(new XsdAlternative());
5247 bool hasTypeSpecified = false;
5249 if (hasAttribute(QString::fromLatin1("test"))) {
5250 const XsdXPathExpression::Ptr expression = readXPathExpression("alternative");
5252 const QString test = readXPathAttribute(QString::fromLatin1("test"), XPath20, "alternative");
5253 expression->setExpression(test);
5255 alternative->setTest(expression);
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
5264 hasTypeSpecified = true;
5267 validateIdAttribute("alternative");
5269 TagValidationHandler tagValidator(XsdTagScope::Alternative, this, m_namePool);
5277 if (isStartElement()) {
5278 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
5279 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
5281 tagValidator.validate(token);
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)) {
5287 const XsdSimpleType::Ptr type = parseLocalSimpleType();
5288 alternative->setType(type);
5290 // add it to list of anonymous types as well
5291 addAnonymousType(type);
5293 hasTypeSpecified = true;
5294 } else if (isSchemaTag(XsdSchemaToken::ComplexType, token, namespaceToken)) {
5295 const XsdComplexType::Ptr type = parseLocalComplexType();
5296 alternative->setType(type);
5298 // add it to list of anonymous types as well
5299 addAnonymousType(type);
5301 hasTypeSpecified = true;
5308 tagValidator.finalize();
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")));
5322 XsdNotation::Ptr XsdSchemaParser::parseNotation()
5324 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Notation, this);
5326 validateElement(XsdTagScope::Notation);
5328 const XsdNotation::Ptr notation(new XsdNotation());
5331 const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("notation"));
5332 notation->setName(objectName);
5334 bool hasOptionalAttribute = false;
5336 if (hasAttribute(QString::fromLatin1("public"))) {
5337 const QString value = readAttribute(QString::fromLatin1("public"));
5338 if (!value.isEmpty()) {
5339 const DerivedString<TypeToken>::Ptr publicId = DerivedString<TypeToken>::fromLexical(m_namePool, value);
5340 if (publicId->hasError()) {
5341 attributeContentError("public", "notation", value, BuiltinTypes::xsToken);
5344 notation->setPublicId(publicId);
5347 hasOptionalAttribute = true;
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);
5357 if (!value.isEmpty()) {
5358 const AnyURI::Ptr systemId = AnyURI::fromLexical(value);
5359 notation->setSystemId(systemId);
5362 hasOptionalAttribute = true;
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")));
5373 validateIdAttribute("notation");
5375 TagValidationHandler tagValidator(XsdTagScope::Notation, this, m_namePool);
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.")));
5390 if (isStartElement()) {
5391 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
5392 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
5394 tagValidator.validate(token);
5396 if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
5397 const XsdAnnotation::Ptr annotation = parseAnnotation();
5398 notation->addAnnotation(annotation);
5405 tagValidator.finalize();
5410 XsdWildcard::Ptr XsdSchemaParser::parseAny(const XsdParticle::Ptr &particle)
5412 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Any, this);
5414 validateElement(XsdTagScope::Any);
5416 const XsdWildcard::Ptr wildcard(new XsdWildcard());
5419 if (!parseMinMaxConstraint(particle, "any")) {
5423 if (hasAttribute(QString::fromLatin1("namespace"))) {
5424 const QSet<QString> values = readAttribute(QString::fromLatin1("namespace")).split(QLatin1Char(' '), QString::SkipEmptyParts).toSet();
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")));
5434 if (values.contains(QString::fromLatin1("##any"))) {
5435 wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any);
5436 } else if (values.contains(QString::fromLatin1("##other"))) {
5437 wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Not);
5438 if (!m_targetNamespace.isEmpty())
5439 wildcard->namespaceConstraint()->setNamespaces(QSet<QString>() << m_targetNamespace);
5441 wildcard->namespaceConstraint()->setNamespaces(QSet<QString>() << XsdWildcard::absentNamespace());
5443 wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Enumeration);
5444 QStringList newValues = values.toList();
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;
5452 newValues[i] = XsdWildcard::absentNamespace();
5453 } else if (newValues.at(i) == QString::fromLatin1("##local")) {
5454 newValues[i] = XsdWildcard::absentNamespace();
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())
5464 if (!isValidUri(stringValue)) {
5465 attributeContentError("namespace", "any", stringValue, BuiltinTypes::xsAnyURI);
5470 wildcard->namespaceConstraint()->setNamespaces(newValues.toSet());
5473 wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any);
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);
5485 if (value == QString::fromLatin1("lax")) {
5486 wildcard->setProcessContents(XsdWildcard::Lax);
5487 } else if (value == QString::fromLatin1("skip")) {
5488 wildcard->setProcessContents(XsdWildcard::Skip);
5489 } else if (value == QString::fromLatin1("strict")) {
5490 wildcard->setProcessContents(XsdWildcard::Strict);
5493 wildcard->setProcessContents(XsdWildcard::Strict);
5496 validateIdAttribute("any");
5498 TagValidationHandler tagValidator(XsdTagScope::Any, this, m_namePool);
5506 if (isStartElement()) {
5507 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
5508 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
5510 tagValidator.validate(token);
5512 if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
5513 const XsdAnnotation::Ptr annotation = parseAnnotation();
5514 wildcard->addAnnotation(annotation);
5521 tagValidator.finalize();
5526 XsdWildcard::Ptr XsdSchemaParser::parseAnyAttribute()
5528 const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::AnyAttribute, this);
5530 validateElement(XsdTagScope::AnyAttribute);
5532 const XsdWildcard::Ptr wildcard(new XsdWildcard());
5535 if (hasAttribute(QString::fromLatin1("namespace"))) {
5536 const QSet<QString> values = readAttribute(QString::fromLatin1("namespace")).split(QLatin1Char(' '), QString::SkipEmptyParts).toSet();
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")));
5546 if (values.contains(QString::fromLatin1("##any"))) {
5547 wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any);
5548 } else if (values.contains(QString::fromLatin1("##other"))) {
5549 wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Not);
5550 if (!m_targetNamespace.isEmpty())
5551 wildcard->namespaceConstraint()->setNamespaces(QSet<QString>() << m_targetNamespace);
5553 wildcard->namespaceConstraint()->setNamespaces(QSet<QString>() << XsdWildcard::absentNamespace());
5555 wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Enumeration);
5556 QStringList newValues = values.toList();
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;
5564 newValues[i] = XsdWildcard::absentNamespace();
5565 } else if (newValues.at(i) == QString::fromLatin1("##local")) {
5566 newValues[i] = XsdWildcard::absentNamespace();
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())
5576 if (!isValidUri(stringValue)) {
5577 attributeContentError("namespace", "anyAttribute", stringValue, BuiltinTypes::xsAnyURI);
5582 wildcard->namespaceConstraint()->setNamespaces(newValues.toSet());
5585 wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any);
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);
5597 if (value == QString::fromLatin1("lax")) {
5598 wildcard->setProcessContents(XsdWildcard::Lax);
5599 } else if (value == QString::fromLatin1("skip")) {
5600 wildcard->setProcessContents(XsdWildcard::Skip);
5601 } else if (value == QString::fromLatin1("strict")) {
5602 wildcard->setProcessContents(XsdWildcard::Strict);
5605 wildcard->setProcessContents(XsdWildcard::Strict);
5608 validateIdAttribute("anyAttribute");
5610 TagValidationHandler tagValidator(XsdTagScope::AnyAttribute, this, m_namePool);
5618 if (isStartElement()) {
5619 const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
5620 const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
5622 tagValidator.validate(token);
5624 if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
5625 const XsdAnnotation::Ptr annotation = parseAnnotation();
5626 wildcard->addAnnotation(annotation);
5633 tagValidator.finalize();
5639 void XsdSchemaParser::parseUnknownDocumentation()
5641 Q_ASSERT(isStartElement());
5642 m_namespaceSupport.pushContext();
5643 m_namespaceSupport.setPrefixes(namespaceDeclarations());
5651 if (isStartElement())
5652 parseUnknownDocumentation();
5655 m_namespaceSupport.popContext();
5658 void XsdSchemaParser::parseUnknown()
5660 Q_ASSERT(isStartElement());
5661 m_namespaceSupport.pushContext();
5662 m_namespaceSupport.setPrefixes(namespaceDeclarations());
5664 error(QtXmlPatterns::tr("%1 element is not allowed in this context.").arg(formatElement(name().toString())));
5672 if (isStartElement())
5676 m_namespaceSupport.popContext();
5679 bool XsdSchemaParser::parseMinMaxConstraint(const XsdParticle::Ptr &particle, const char *elementName)
5681 if (hasAttribute(QString::fromLatin1("minOccurs"))) {
5682 const QString value = readAttribute(QString::fromLatin1("minOccurs"));
5684 DerivedInteger<TypeNonNegativeInteger>::Ptr integer = DerivedInteger<TypeNonNegativeInteger>::fromLexical(m_namePool, value);
5685 if (integer->hasError()) {
5686 attributeContentError("minOccurs", elementName, value, BuiltinTypes::xsNonNegativeInteger);
5689 particle->setMinimumOccurs(integer->as< DerivedInteger<TypeNonNegativeInteger> >()->storedValue());
5692 particle->setMinimumOccurs(1);
5695 if (hasAttribute(QString::fromLatin1("maxOccurs"))) {
5696 const QString value = readAttribute(QString::fromLatin1("maxOccurs"));
5698 if (value == QString::fromLatin1("unbounded")) {
5699 particle->setMaximumOccursUnbounded(true);
5701 particle->setMaximumOccursUnbounded(false);
5702 DerivedInteger<TypeNonNegativeInteger>::Ptr integer = DerivedInteger<TypeNonNegativeInteger>::fromLexical(m_namePool, value);
5703 if (integer->hasError()) {
5704 attributeContentError("maxOccurs", elementName, value, BuiltinTypes::xsNonNegativeInteger);
5707 particle->setMaximumOccurs(integer->as< DerivedInteger<TypeNonNegativeInteger> >()->storedValue());
5711 particle->setMaximumOccursUnbounded(false);
5712 particle->setMaximumOccurs(1);
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")));
5728 QSourceLocation XsdSchemaParser::currentSourceLocation() const
5730 QSourceLocation location;
5731 location.setLine(lineNumber());
5732 location.setColumn(columnNumber());
5733 location.setUri(m_documentURI);
5738 void XsdSchemaParser::convertName(const QString &qualifiedName, NamespaceSupport::NameType type, QXmlName &name)
5740 bool result = m_namespaceSupport.processName(qualifiedName, type, name);
5742 error(QtXmlPatterns::tr("Prefix of qualified name %1 is not defined.").arg(formatKeyword(qualifiedName)));
5746 QString XsdSchemaParser::readNameAttribute(const char *elementName)
5748 const QString value = readAttribute(QString::fromLatin1("name")).simplified();
5749 if (!QXmlUtils::isNCName(value)) {
5750 attributeContentError("name", elementName, value, BuiltinTypes::xsNCName);
5757 QString XsdSchemaParser::readQNameAttribute(const QString &typeAttribute, const char *elementName)
5759 const QString value = readAttribute(typeAttribute).simplified();
5760 if (!XPathHelper::isQName(value)) {
5761 attributeContentError(typeAttribute.toLatin1(), elementName, value, BuiltinTypes::xsQName);
5768 QString XsdSchemaParser::readNamespaceAttribute(const QString &attributeName, const char *elementName)
5770 const QString value = readAttribute(attributeName);
5771 if (value.isEmpty()) {
5772 attributeContentError(attributeName.toLatin1(), elementName, value, BuiltinTypes::xsAnyURI);
5779 SchemaType::DerivationConstraints XsdSchemaParser::readDerivationConstraintAttribute(const SchemaType::DerivationConstraints &allowedConstraints, const char *elementName)
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"));
5792 // read content from the attribute if available, otherwise use the default definitions from the schema tag
5794 if (hasAttribute(QString::fromLatin1("final"))) {
5795 content = readAttribute(QString::fromLatin1("final"));
5797 // split string into list to validate the content of the attribute
5798 const QStringList values = content.split(QLatin1Char(' '), QString::SkipEmptyParts);
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();
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();
5815 // content of the default value has been validated in parseSchema already
5816 content = m_finalDefault;
5819 QSet<QString> contentSet = content.split(QLatin1Char(' '), QString::SkipEmptyParts).toSet();
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);
5827 SchemaType::DerivationConstraints constraints;
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;
5842 NamedSchemaComponent::BlockingConstraints XsdSchemaParser::readBlockingConstraintAttribute(const NamedSchemaComponent::BlockingConstraints &allowedConstraints, const char *elementName)
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"));
5853 // read content from the attribute if available, otherwise use the default definitions from the schema tag
5855 if (hasAttribute(QString::fromLatin1("block"))) {
5856 content = readAttribute(QString::fromLatin1("block"));
5858 // split string into list to validate the content of the attribute
5859 const QStringList values = content.split(QLatin1Char(' '), QString::SkipEmptyParts);
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();
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();
5876 // content of the default value has been validated in parseSchema already
5877 content = m_blockDefault;
5880 QSet<QString> contentSet = content.split(QLatin1Char(' '), QString::SkipEmptyParts).toSet();
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);
5888 NamedSchemaComponent::BlockingConstraints constraints;
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;
5901 XsdXPathExpression::Ptr XsdSchemaParser::readXPathExpression(const char *elementName)
5903 const XsdXPathExpression::Ptr expression(new XsdXPathExpression());
5905 const QList<QXmlName> namespaceBindings = m_namespaceSupport.namespaceBindings();
5907 for (int i = 0; i < namespaceBindings.count(); ++i) {
5908 if (namespaceBindings.at(i).prefix() == StandardPrefixes::empty)
5909 emptyName = namespaceBindings.at(i);
5912 expression->setNamespaceBindings(namespaceBindings);
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);
5926 xpathDefaultNamespace = m_xpathDefaultNamespace;
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")) {
5939 namespaceURI = AnyURI::fromLexical(xpathDefaultNamespace);
5942 if (namespaceURI->hasError()) {
5943 attributeContentError("xpathDefaultNamespace", elementName, xpathDefaultNamespace, BuiltinTypes::xsAnyURI);
5947 expression->setDefaultNamespace(namespaceURI);
5950 //TODO: read the base uri if qmaintaining reader support it
5955 QString XsdSchemaParser::readXPathAttribute(const QString &attributeName, XPathType type, const char *elementName)
5957 const QString value = readAttribute(attributeName);
5958 if (value.isEmpty() || value.startsWith(QLatin1Char('/'))) {
5959 attributeContentError(attributeName.toLatin1(), elementName, value);
5963 QXmlNamePool namePool(m_namePool.data());
5965 QXmlQuery::QueryLanguage language = QXmlQuery::XPath20;
5967 case XPath20: language = QXmlQuery::XPath20; break;
5968 case XPathSelector: language = QXmlQuery::XmlSchema11IdentityConstraintSelector; break;
5969 case XPathField: language = QXmlQuery::XmlSchema11IdentityConstraintField; break;
5972 QXmlQuery query(language, namePool);
5973 QXmlQueryPrivate *queryPrivate = query.d;
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));
5981 query.setQuery(value, m_documentURI);
5982 if (!query.isValid()) {
5983 attributeContentError(attributeName.toLatin1(), elementName, value);
5990 void XsdSchemaParser::validateIdAttribute(const char *elementName)
5992 if (hasAttribute(QString::fromLatin1("id"))) {
5993 const QString value = readAttribute(QString::fromLatin1("id"));
5994 DerivedString<TypeID>::Ptr id = DerivedString<TypeID>::fromLexical(m_namePool, value);
5995 if (id->hasError()) {
5996 attributeContentError("id", elementName, value, BuiltinTypes::xsID);
5998 if (m_idCache->hasId(value)) {
5999 error(QtXmlPatterns::tr("Component with ID %1 has been defined previously.").arg(formatData(value)));
6001 m_idCache->addId(value);
6007 bool XsdSchemaParser::isSchemaTag(XsdSchemaToken::NodeName tag, XsdSchemaToken::NodeName token, XsdSchemaToken::NodeName namespaceToken) const
6009 return ((tag == token) && (namespaceToken == XsdSchemaToken::XML_NS_SCHEMA_URI));
6012 void XsdSchemaParser::addElement(const XsdElement::Ptr &element)
6014 const QXmlName objectName = element->name(m_namePool);
6015 if (m_schema->element(objectName)) {
6016 error(QtXmlPatterns::tr("Element %1 already defined.").arg(formatElement(m_namePool->displayName(objectName))));
6018 m_schema->addElement(element);
6019 m_componentLocationHash.insert(element, currentSourceLocation());
6023 void XsdSchemaParser::addAttribute(const XsdAttribute::Ptr &attribute)
6025 const QXmlName objectName = attribute->name(m_namePool);
6026 if (m_schema->attribute(objectName)) {
6027 error(QtXmlPatterns::tr("Attribute %1 already defined.").arg(formatAttribute(m_namePool->displayName(objectName))));
6029 m_schema->addAttribute(attribute);
6030 m_componentLocationHash.insert(attribute, currentSourceLocation());
6034 void XsdSchemaParser::addType(const SchemaType::Ptr &type)
6036 // we don't import redefinitions of builtin types, that just causes problems
6037 if (m_builtinTypeNames.contains(type->name(m_namePool)))
6040 const QXmlName objectName = type->name(m_namePool);
6041 if (m_schema->type(objectName)) {
6042 error(QtXmlPatterns::tr("Type %1 already defined.").arg(formatType(m_namePool, objectName)));
6044 m_schema->addType(type);
6045 if (type->isSimpleType())
6046 m_componentLocationHash.insert(XsdSimpleType::Ptr(type), currentSourceLocation());
6048 m_componentLocationHash.insert(XsdComplexType::Ptr(type), currentSourceLocation());
6052 void XsdSchemaParser::addAnonymousType(const SchemaType::Ptr &type)
6054 m_schema->addAnonymousType(type);
6055 if (type->isSimpleType())
6056 m_componentLocationHash.insert(XsdSimpleType::Ptr(type), currentSourceLocation());
6058 m_componentLocationHash.insert(XsdComplexType::Ptr(type), currentSourceLocation());
6061 void XsdSchemaParser::addAttributeGroup(const XsdAttributeGroup::Ptr &group)
6063 const QXmlName objectName = group->name(m_namePool);
6064 if (m_schema->attributeGroup(objectName)) {
6065 error(QtXmlPatterns::tr("Attribute group %1 already defined.").arg(formatKeyword(m_namePool, objectName)));
6067 m_schema->addAttributeGroup(group);
6068 m_componentLocationHash.insert(group, currentSourceLocation());
6072 void XsdSchemaParser::addElementGroup(const XsdModelGroup::Ptr &group)
6074 const QXmlName objectName = group->name(m_namePool);
6075 if (m_schema->elementGroup(objectName)) {
6076 error(QtXmlPatterns::tr("Element group %1 already defined.").arg(formatKeyword(m_namePool, objectName)));
6078 m_schema->addElementGroup(group);
6079 m_componentLocationHash.insert(group, currentSourceLocation());
6083 void XsdSchemaParser::addNotation(const XsdNotation::Ptr ¬ation)
6085 const QXmlName objectName = notation->name(m_namePool);
6086 if (m_schema->notation(objectName)) {
6087 error(QtXmlPatterns::tr("Notation %1 already defined.").arg(formatKeyword(m_namePool, objectName)));
6089 m_schema->addNotation(notation);
6090 m_componentLocationHash.insert(notation, currentSourceLocation());
6094 void XsdSchemaParser::addIdentityConstraint(const XsdIdentityConstraint::Ptr &constraint)
6096 const QXmlName objectName = constraint->name(m_namePool);
6097 if (m_schema->identityConstraint(objectName)) {
6098 error(QtXmlPatterns::tr("Identity constraint %1 already defined.").arg(formatKeyword(m_namePool, objectName)));
6100 m_schema->addIdentityConstraint(constraint);
6101 m_componentLocationHash.insert(constraint, currentSourceLocation());
6105 void XsdSchemaParser::addFacet(const XsdFacet::Ptr &facet, XsdFacet::Hash &facets, const SchemaType::Ptr &type)
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(m_namePool, type)));
6113 facets.insert(facet->type(), facet);