TraverseSchema.cpp
上传用户:huihehuasu
上传日期:2007-01-10
资源大小:6948k
文件大小:304k
源码类别:
xml/soap/webservice
开发平台:
C/C++
- if (typeInfo->getBaseComplexTypeInfo() == 0) {
- reportSchemaError(XMLUni::fgXMLErrDomain,
- XMLErrs::BaseNotComplexType);
- throw TraverseSchema::InvalidComplexTypeInfo;
- }
- }
- // -----------------------------------------------------------------------
- // Process the content of the derivation
- // -----------------------------------------------------------------------
- //Skip over any annotations in the restriction or extension elements
- DOM_Element content = checkContent(complexContent,
- XUtil::getFirstChildElement(complexContent), true);
- processComplexContent(typeName, content, typeInfo, baseName, localPart,
- uri, mixedContent, isBaseAnyType);
- if (XUtil::getNextSiblingElement(complexContent) != 0) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidChildInComplexContent);
- }
- }
- /**
- * <anyAttribute
- * id = ID
- * namespace = ((##any | ##other) | list of (anyURI | (##targetNamespace | ##local)))>
- * processContents = (lax | skip | strict) : strict
- * Content: (annotation?)
- * </anyAttribute>
- */
- SchemaAttDef* TraverseSchema::traverseAnyAttribute(const DOM_Element& elem) {
- // -----------------------------------------------------------------------
- // Check Attributes
- // -----------------------------------------------------------------------
- unsigned short scope = GeneralAttributeCheck::LocalContext;
- fAttributeCheck.checkAttributes(elem, scope, this);
- // ------------------------------------------------------------------
- // First, handle any ANNOTATION declaration
- // ------------------------------------------------------------------
- if (checkContent(elem, XUtil::getFirstChildElement(elem), true) != 0) {
- reportSchemaError(XMLUni::fgXMLErrDomain,
- XMLErrs::AnyAttributeContentError);
- }
- // ------------------------------------------------------------------
- // Get attributes
- // ------------------------------------------------------------------
- const XMLCh* const processContents =
- getElementAttValue(elem, SchemaSymbols::fgATT_PROCESSCONTENTS);
- const XMLCh* const nameSpace =
- getElementAttValue(elem, SchemaSymbols::fgATT_NAMESPACE);
- // ------------------------------------------------------------------
- // Set default att type based on 'processContents' value
- // ------------------------------------------------------------------
- XMLAttDef::DefAttTypes attDefType = XMLAttDef::ProcessContents_Strict;
- if (XMLString::stringLen(processContents) == 0
- || XMLString::compareString(processContents, SchemaSymbols::fgATTVAL_STRICT) == 0) {
- // Do nothing - defaulted already
- }
- else if (XMLString::compareString(processContents,
- SchemaSymbols::fgATTVAL_SKIP) == 0) {
- attDefType = XMLAttDef::ProcessContents_Skip;
- }
- else if (XMLString::compareString(processContents,
- SchemaSymbols::fgATTVAL_LAX) == 0) {
- attDefType = XMLAttDef::ProcessContents_Lax;
- }
- // ------------------------------------------------------------------
- // Process 'namespace' attribute
- // ------------------------------------------------------------------
- int uriIndex = fEmptyNamespaceURI;
- XMLAttDef::AttTypes attType = XMLAttDef::Any_Any;
- ValueVectorOf<unsigned int> namespaceList(8);
- if (XMLString::stringLen(nameSpace) == 0
- || XMLString::compareString(nameSpace, SchemaSymbols::fgATTVAL_TWOPOUNDANY) == 0) {
- // Do nothing - defaulted already
- }
- else if (XMLString::compareString(nameSpace, SchemaSymbols::fgATTVAL_TWOPOUNDOTHER) == 0) {
- attType = XMLAttDef::Any_Other;
- uriIndex = fTargetNSURI;
- }
- else {
- XMLStringTokenizer tokenizer(nameSpace);
- attType = XMLAttDef::Any_List;
- while (tokenizer.hasMoreTokens()) {
- const XMLCh* token = tokenizer.nextToken();
- if (!XMLString::compareString(token, SchemaSymbols::fgATTVAL_TWOPOUNDLOCAL)) {
- uriIndex = fEmptyNamespaceURI;
- }
- else if (!XMLString::compareString(token, SchemaSymbols::fgATTVAL_TWOPOUNDTRAGETNAMESPACE)) {
- uriIndex = fTargetNSURI;
- }
- else {
- uriIndex = fURIStringPool->addOrFind(token);
- }
- if (!namespaceList.containsElement(uriIndex)) {
- namespaceList.addElement(uriIndex);
- }
- }
- uriIndex = fEmptyNamespaceURI;
- }
- // ------------------------------------------------------------------
- // Create wildcard attribute
- // ------------------------------------------------------------------
- SchemaAttDef* attDef = new SchemaAttDef(XMLUni::fgZeroLenString,
- XMLUni::fgZeroLenString,
- uriIndex, attType, attDefType);
- if (namespaceList.size()) {
- attDef->setNamespaceList(&namespaceList);
- }
- return attDef;
- }
- /**
- * <key
- * id = ID
- * name = NCName
- * Content: (annotation?, (selector, field+))
- * </key>
- */
- void TraverseSchema::traverseKey(const DOM_Element& icElem,
- SchemaElementDecl* const elemDecl) {
- // -----------------------------------------------------------------------
- // Check Attributes
- // -----------------------------------------------------------------------
- unsigned short scope = GeneralAttributeCheck::LocalContext;
- fAttributeCheck.checkAttributes(icElem, scope, this);
- // -----------------------------------------------------------------------
- // Create identity constraint
- // -----------------------------------------------------------------------
- const XMLCh* name = getElementAttValue(icElem, SchemaSymbols::fgATT_NAME);
- if (!XMLString::stringLen(name)) {
- return;
- }
- if (!XMLString::isValidNCName(name)) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName,
- SchemaSymbols::fgELT_KEY, name);
- return;
- }
- if (!fIdentityConstraintNames) {
- fIdentityConstraintNames = new RefHash2KeysTableOf<IdentityConstraint>(29, false);
- }
- if (fIdentityConstraintNames->containsKey(name, fTargetNSURI)) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::IC_DuplicateDecl, name);
- return;
- }
- IC_Key* icKey = new IC_Key(name, elemDecl->getBaseName());
- Janitor<IC_Key> janKey(icKey);
- fIdentityConstraintNames->put((void*) name, fTargetNSURI, icKey);
- // -----------------------------------------------------------------------
- // Get selector and fields
- // -----------------------------------------------------------------------
- if (!traverseIdentityConstraint(icKey, icElem)) {
- fIdentityConstraintNames->put((void*) name, fTargetNSURI, 0);
- return;
- }
- // -----------------------------------------------------------------------
- // Add key to element declaration
- // -----------------------------------------------------------------------
- elemDecl->addIdentityConstraint(icKey);
- janKey.orphan();
- }
- /**
- * <unique
- * id = ID
- * name = NCName
- * Content: (annotation?, (selector, field+))
- * </unique>
- */
- void TraverseSchema::traverseUnique(const DOM_Element& icElem,
- SchemaElementDecl* const elemDecl) {
- // -----------------------------------------------------------------------
- // Check Attributes
- // -----------------------------------------------------------------------
- unsigned short scope = GeneralAttributeCheck::LocalContext;
- fAttributeCheck.checkAttributes(icElem, scope, this);
- // -----------------------------------------------------------------------
- // Create identity constraint
- // -----------------------------------------------------------------------
- const XMLCh* name = getElementAttValue(icElem, SchemaSymbols::fgATT_NAME);
- if (!XMLString::stringLen(name)) {
- return;
- }
- if (!XMLString::isValidNCName(name)) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName,
- SchemaSymbols::fgELT_UNIQUE, name);
- return;
- }
- if (!fIdentityConstraintNames) {
- fIdentityConstraintNames = new RefHash2KeysTableOf<IdentityConstraint>(29, false);
- }
- if (fIdentityConstraintNames->containsKey(name, fTargetNSURI)) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::IC_DuplicateDecl, name);
- return;
- }
- IC_Unique* icUnique = new IC_Unique(name, elemDecl->getBaseName());
- Janitor<IC_Unique> janUnique(icUnique);
- fIdentityConstraintNames->put((void*) name, fTargetNSURI, icUnique);
- // -----------------------------------------------------------------------
- // Get selector and fields
- // -----------------------------------------------------------------------
- if (!traverseIdentityConstraint(icUnique, icElem)) {
- fIdentityConstraintNames->put((void*) name, fTargetNSURI, 0);
- return;
- }
- // -----------------------------------------------------------------------
- // Add identity cosntraints to element declaration
- // -----------------------------------------------------------------------
- elemDecl->addIdentityConstraint(icUnique);
- janUnique.orphan();
- }
- /**
- * <keyref
- * id = ID
- * name = NCName
- * refer = QName
- * Content: (annotation?, (selector, field+))
- * </keyref>
- */
- void TraverseSchema::traverseKeyRef(const DOM_Element& icElem,
- SchemaElementDecl* const elemDecl,
- const unsigned int namespaceDepth) {
- // -----------------------------------------------------------------------
- // Check Attributes
- // -----------------------------------------------------------------------
- unsigned short scope = GeneralAttributeCheck::LocalContext;
- fAttributeCheck.checkAttributes(icElem, scope, this);
- // -----------------------------------------------------------------------
- // Verify that key reference "refer" attribute is valid
- // -----------------------------------------------------------------------
- const XMLCh* name = getElementAttValue(icElem, SchemaSymbols::fgATT_NAME);
- const XMLCh* refer = getElementAttValue(icElem, SchemaSymbols::fgATT_REFER);
- if (!XMLString::stringLen(name) || !XMLString::stringLen(refer)) {
- return;
- }
- if (!XMLString::isValidNCName(name)) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName,
- SchemaSymbols::fgELT_KEYREF, name);
- return;
- }
- const XMLCh* prefix = getPrefix(refer);
- const XMLCh* localPart = getLocalPart(refer);
- const XMLCh* uriStr = resolvePrefixToURI(prefix, namespaceDepth);
- IdentityConstraint* icKey = (fIdentityConstraintNames)
- ? fIdentityConstraintNames->get(localPart, fURIStringPool->addOrFind(uriStr)) : 0;
- if (!icKey) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::IC_KeyRefReferNotFound, name, localPart);
- return;
- }
- // -----------------------------------------------------------------------
- // Create identity constraint
- // -----------------------------------------------------------------------
- if(fIdentityConstraintNames->containsKey(name, fTargetNSURI)) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::IC_DuplicateDecl, name);
- return;
- }
- IC_KeyRef* icKeyRef = new IC_KeyRef(name, elemDecl->getBaseName(), icKey);
- Janitor<IC_KeyRef> janKeyRef(icKeyRef);
- fIdentityConstraintNames->put((void*) name, fTargetNSURI, icKeyRef);
- // -----------------------------------------------------------------------
- // Get selector and fields
- // -----------------------------------------------------------------------
- if (!traverseIdentityConstraint(icKeyRef, icElem)) {
- fIdentityConstraintNames->put((void*) name, fTargetNSURI, 0);
- return;
- }
- // -----------------------------------------------------------------------
- // Add key reference to element decl
- // -----------------------------------------------------------------------
- if (icKeyRef->getFieldCount() != icKey->getFieldCount()) {
- fIdentityConstraintNames->put((void*) name, fTargetNSURI, 0);
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::IC_KeyRefCardinality,
- name, icKey->getIdentityConstraintName());
- }
- else {
- elemDecl->addIdentityConstraint(icKeyRef);
- janKeyRef.orphan();
- }
- }
- bool TraverseSchema::traverseIdentityConstraint(IdentityConstraint* const ic,
- const DOM_Element& icElem) {
- // ------------------------------------------------------------------
- // First, handle any ANNOTATION declaration
- // ------------------------------------------------------------------
- unsigned short scope = GeneralAttributeCheck::LocalContext;
- DOM_Element elem = XUtil::getFirstChildElement(icElem);
- if (elem == 0) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::IC_BadContent);
- return false;
- }
- elem = checkContent(icElem, elem, false);
- // ------------------------------------------------------------------
- // Get selector
- // ------------------------------------------------------------------
- if (!elem.getLocalName().equals(SchemaSymbols::fgELT_SELECTOR)) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::IC_BadContent);
- return false;
- }
- fAttributeCheck.checkAttributes(elem, scope, this);
- checkContent(icElem, XUtil::getFirstChildElement(elem), true);
- // ------------------------------------------------------------------
- // Get xpath attribute
- // ------------------------------------------------------------------
- const XMLCh* xpathExpr = getElementAttValue(elem, SchemaSymbols::fgATT_XPATH, true);
- unsigned int xpathLen = XMLString::stringLen(xpathExpr);
- if (!xpathExpr || !xpathLen) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::IC_XPathExprMissing);
- return false;
- }
- fBuffer.reset();
- unsigned int startIndex = 0;
- while (startIndex < xpathLen) {
- if (!XMLString::startsWith(xpathExpr + startIndex, fgForwardSlash)
- && !XMLString::startsWith(xpathExpr + startIndex, fgDot)) {
- fBuffer.append(fgDotForwardSlash);
- }
- int chOffset = XMLString::indexOf(xpathExpr, chPipe, startIndex);
- if (chOffset == -1)
- break;
- fBuffer.append(xpathExpr + startIndex, chOffset + 1);
- startIndex = chOffset + 1;
- }
- if (startIndex < xpathLen)
- fBuffer.append(xpathExpr + startIndex);
- // ------------------------------------------------------------------
- // Parse xpath expression
- // ------------------------------------------------------------------
- try {
- XercesXPath* sXPath = new XercesXPath(fBuffer.getRawBuffer(), fStringPool, fNamespaceScope, fEmptyNamespaceURI, true);
- IC_Selector* icSelector = new IC_Selector(sXPath, ic);
- ic->setSelector(icSelector);
- }
- catch (const XPathException& e) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DisplayErrorMessage, e.getMessage());
- return false;
- }
- // ------------------------------------------------------------------
- // Get fields
- // ------------------------------------------------------------------
- elem = XUtil::getNextSiblingElement(elem);
- if (elem == 0) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::IC_BadContent);
- return false;
- }
- while (elem != 0) {
- if (!elem.getLocalName().equals(SchemaSymbols::fgELT_FIELD)) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::IC_BadContent);
- }
- else {
- // General Attribute Checking
- fAttributeCheck.checkAttributes(elem, scope, this);
- checkContent(icElem, XUtil::getFirstChildElement(elem), true);
- // xpath expression parsing
- xpathExpr = getElementAttValue(elem, SchemaSymbols::fgATT_XPATH, true);
- if (!xpathExpr || !XMLString::stringLen(xpathExpr)) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::IC_XPathExprMissing);
- return false;
- }
- if (XMLString::startsWith(xpathExpr, fgForwardSlash)
- || XMLString::startsWith(xpathExpr, fgDot)) {
- fBuffer.set(xpathExpr);
- }
- else {
- fBuffer.set(fgDotForwardSlash);
- fBuffer.append(xpathExpr);
- }
- try {
- XercesXPath* fieldXPath = new XercesXPath(fBuffer.getRawBuffer(), fStringPool, fNamespaceScope, fEmptyNamespaceURI);
- IC_Field* icField = new IC_Field(fieldXPath, ic);
- ic->addField(icField);
- }
- catch (const XPathException& e) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DisplayErrorMessage, e.getMessage());
- return false;
- }
- }
- elem = XUtil::getNextSiblingElement(elem);
- }
- if (ic->getFieldCount() == 0) {
- return false;
- }
- return true;
- }
- // ---------------------------------------------------------------------------
- // TraverseSchema: Helper methods
- // ---------------------------------------------------------------------------
- void TraverseSchema::retrieveNamespaceMapping(const DOM_Element& schemaRoot) {
- DOM_NamedNodeMap schemaEltAttrs = schemaRoot.getAttributes();
- bool seenXMLNS = false;
- int attrCount = schemaEltAttrs.getLength();
- for (int i = 0; i < attrCount; i++) {
- DOM_Node attribute = schemaEltAttrs.item(i);
- if (attribute.isNull()) {
- break;
- }
- DOMString attName = attribute.getNodeName();
- fBuffer.set(attName.rawBuffer(), attName.length());
- int nameId = fStringPool->addOrFind(fBuffer.getRawBuffer());
- const XMLCh* name = fStringPool->getValueForId(nameId);
- // starts with 'xmlns:'
- if (XMLString::startsWith(name, fgXMLNS_Str)) {
- XMLCh prefix[256];
- int offsetIndex = XMLString::indexOf(name, chColon);
- DOMString attValue = attribute.getNodeValue();
- XMLString::subString(prefix, name, offsetIndex + 1, XMLString::stringLen(name));
- fBuffer.set(attValue.rawBuffer(), attValue.length());
- fNamespaceScope->addPrefix(prefix, fURIStringPool->addOrFind(fBuffer.getRawBuffer()));
- }
- else if (attName.equals(XMLUni::fgXMLNSString)) { // == 'xmlns'
- DOMString attValue = attribute.getNodeValue();
- fBuffer.set(attValue.rawBuffer(), attValue.length());
- fNamespaceScope->addPrefix( XMLUni::fgZeroLenString, fURIStringPool->addOrFind(fBuffer.getRawBuffer()));
- seenXMLNS = true;
- }
- } // end for
- if (!seenXMLNS && XMLString::stringLen(fTargetNSURIString) == 0 ) {
- fNamespaceScope->addPrefix(XMLUni::fgZeroLenString, fEmptyNamespaceURI);
- }
- }
- void TraverseSchema::processChildren(const DOM_Element& root) {
- // process <redefine>, <include> and <import> info items.
- DOM_Element child = XUtil::getFirstChildElement(root);
- for (; child != 0; child = XUtil::getNextSiblingElement(child)) {
- DOMString name = child.getLocalName();
- if (name.equals(SchemaSymbols::fgELT_ANNOTATION)) {
- traverseAnnotationDecl(child);
- }
- else if (name.equals(SchemaSymbols::fgELT_INCLUDE)) {
- traverseInclude(child);
- }
- else if (name.equals(SchemaSymbols::fgELT_IMPORT)) {
- traverseImport(child);
- }
- else if (name.equals(SchemaSymbols::fgELT_REDEFINE)) {
- traverseRedefine(child);
- }
- else
- break;
- }
- // child refers to the first info item which is not <annotation> or
- // one of the schema inclusion/importation declarations.
- for (; child != 0; child = XUtil::getNextSiblingElement(child)) {
- DOMString name = child.getLocalName();
- const XMLCh* typeName = getElementAttValue(child, SchemaSymbols::fgATT_NAME);
- int fullNameId = 0;
- if (typeName) {
- fBuffer.set(fTargetNSURIString);
- fBuffer.append(chComma);
- fBuffer.append(typeName);
- fullNameId = fStringPool->addOrFind(fBuffer.getRawBuffer());
- }
- if (name.equals(SchemaSymbols::fgELT_ANNOTATION)) {
- traverseAnnotationDecl(child);
- }
- else if (name.equals(SchemaSymbols::fgELT_SIMPLETYPE)) {
- if (XMLString::stringLen(typeName)) {
- if (fGlobalDeclarations->containsKey(SchemaSymbols::fgELT_SIMPLETYPE, fullNameId)
- || fGlobalDeclarations->containsKey(SchemaSymbols::fgELT_COMPLEXTYPE, fullNameId)) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateGlobalType,
- SchemaSymbols::fgELT_SIMPLETYPE, typeName, SchemaSymbols::fgELT_COMPLEXTYPE);
- continue;
- }
- else {
- fGlobalDeclarations->put((void*) SchemaSymbols::fgELT_SIMPLETYPE, fullNameId, 0);
- }
- }
- traverseSimpleTypeDecl(child);
- }
- else if (name.equals(SchemaSymbols::fgELT_COMPLEXTYPE)) {
- if (XMLString::stringLen(typeName)) {
- if (fGlobalDeclarations->containsKey(SchemaSymbols::fgELT_SIMPLETYPE, fullNameId)
- || fGlobalDeclarations->containsKey(SchemaSymbols::fgELT_COMPLEXTYPE, fullNameId)) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateGlobalType,
- SchemaSymbols::fgELT_COMPLEXTYPE, typeName, SchemaSymbols::fgELT_SIMPLETYPE);
- continue;
- }
- else {
- fGlobalDeclarations->put((void*) SchemaSymbols::fgELT_COMPLEXTYPE, fullNameId, 0);
- }
- }
- traverseComplexTypeDecl(child);
- }
- else if (name.equals(SchemaSymbols::fgELT_ELEMENT)) {
- if (XMLString::stringLen(typeName)) {
- if (fGlobalDeclarations->containsKey(SchemaSymbols::fgELT_ELEMENT, fullNameId)) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateGlobalDeclaration,
- SchemaSymbols::fgELT_ELEMENT, typeName);
- continue;
- }
- else {
- fGlobalDeclarations->put((void*) SchemaSymbols::fgELT_ELEMENT, fullNameId, 0);
- }
- }
- bool toDelete = true;
- QName* elmQName = traverseElementDecl(child, toDelete);
- delete elmQName;
- }
- else if (name.equals(SchemaSymbols::fgELT_ATTRIBUTEGROUP)) {
- if (XMLString::stringLen(typeName)) {
- if (fGlobalDeclarations->containsKey(SchemaSymbols::fgELT_ATTRIBUTEGROUP, fullNameId)) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateGlobalDeclaration,
- SchemaSymbols::fgELT_ATTRIBUTEGROUP, typeName);
- continue;
- }
- else {
- fGlobalDeclarations->put((void*) SchemaSymbols::fgELT_ATTRIBUTEGROUP, fullNameId, 0);
- }
- }
- if (!typeName || !fAttGroupRegistry->containsKey(typeName)) {
- traverseAttributeGroupDecl(child, 0);
- }
- }
- else if (name.equals(SchemaSymbols::fgELT_ATTRIBUTE)) {
- if (XMLString::stringLen(typeName)) {
- if (fGlobalDeclarations->containsKey(SchemaSymbols::fgELT_ATTRIBUTE, fullNameId)) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateAttribute, typeName);
- continue;
- }
- else {
- fGlobalDeclarations->put((void*) SchemaSymbols::fgELT_ATTRIBUTE, fullNameId, 0);
- }
- }
- if (!typeName || !fAttributeDeclRegistry->containsKey(typeName)) {
- traverseAttributeDecl( child, 0);
- }
- }
- else if (name.equals(SchemaSymbols::fgELT_GROUP)) {
- if (XMLString::stringLen(typeName)) {
- if (fGlobalDeclarations->containsKey(SchemaSymbols::fgELT_GROUP, fullNameId)) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateGlobalDeclaration,
- SchemaSymbols::fgELT_GROUP, typeName);
- continue;
- }
- else {
- fGlobalDeclarations->put((void*) SchemaSymbols::fgELT_GROUP, fullNameId, 0);
- }
- }
- if (!typeName || !fGroupRegistry->containsKey(fBuffer.getRawBuffer())) {
- traverseGroupDecl(child);
- }
- }
- else if (name.equals(SchemaSymbols::fgELT_NOTATION)) {
- traverseNotationDecl(child);
- } else {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::SchemaElementContentError);
- }
- } // for each child node
- }
- DOM_Element TraverseSchema::checkContent(const DOM_Element& rootElem,
- const DOM_Element& contentElem,
- const bool isEmpty) {
- DOM_Element content = contentElem;
- const XMLCh* name = getElementAttValue(rootElem,SchemaSymbols::fgATT_NAME);
- if (content == 0) {
- if (!isEmpty) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::ContentError, name);
- }
- return 0;
- }
- if (content.getLocalName().equals(SchemaSymbols::fgELT_ANNOTATION)) {
- traverseAnnotationDecl(contentElem);
- content = XUtil::getNextSiblingElement(content);
- if (content == 0) { // must be followed by content
- if (!isEmpty) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::ContentError, name);
- }
- return 0;
- }
- if (content.getLocalName().equals(SchemaSymbols::fgELT_ANNOTATION)) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::AnnotationError, name);
- return 0;
- }
- }
- return content;
- }
- DatatypeValidator*
- TraverseSchema::getDatatypeValidator(const XMLCh* const uriStr,
- const XMLCh* const localPartStr) {
- DatatypeValidator* dv = 0;
- if (XMLString::compareString(uriStr, SchemaSymbols::fgURI_SCHEMAFORSCHEMA) == 0) {
- dv = fDatatypeRegistry->getDatatypeValidator(localPartStr);
- }
- else {
- fBuffer.set(uriStr);
- fBuffer.append(chComma);
- fBuffer.append(localPartStr);
- dv = fDatatypeRegistry->getDatatypeValidator(fBuffer.getRawBuffer());
- }
- return dv;
- }
- XMLCh* TraverseSchema::getQualifiedName(const int typeNameIndex) {
- const XMLCh* typeName = fStringPool->getValueForId(typeNameIndex);
- fBuffer.set(fTargetNSURIString);
- fBuffer.append(chComma);
- fBuffer.append(typeName);
- return fBuffer.getRawBuffer();
- }
- DatatypeValidator*
- TraverseSchema::checkForSimpleTypeValidator(const DOM_Element& content,
- int baseRefContext) {
- int typeNameIndex = traverseSimpleTypeDecl(content, baseRefContext);
- DatatypeValidator* baseValidator = 0;
- if (typeNameIndex != -1) {
- baseValidator = fDatatypeRegistry->getDatatypeValidator(
- fStringPool->getValueForId(typeNameIndex));
- }
- if (typeNameIndex == -1 || baseValidator == 0) {
- const XMLCh* name = getElementAttValue(content,SchemaSymbols::fgATT_NAME);
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::UnknownSimpleType, name);
- }
- return baseValidator;
- }
- ComplexTypeInfo*
- TraverseSchema::checkForComplexTypeInfo(const DOM_Element& content) {
- int typeNameIndex = traverseComplexTypeDecl(content);
- ComplexTypeInfo* baseTypeInfo = 0;
- if (typeNameIndex != -1) {
- baseTypeInfo = fComplexTypeRegistry->get(
- fStringPool->getValueForId(typeNameIndex));
- }
- if (typeNameIndex == -1 || baseTypeInfo == 0) {
- const XMLCh* name = getElementAttValue(content,SchemaSymbols::fgATT_NAME);
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::UnknownComplexType, name);
- }
- return baseTypeInfo;
- }
- DatatypeValidator*
- TraverseSchema::findDTValidator(const DOM_Element& rootElem,
- const XMLCh* const baseTypeStr,
- const int baseRefContext) {
- const XMLCh* prefix = getPrefix(baseTypeStr);
- const XMLCh* localPart = getLocalPart(baseTypeStr);
- const XMLCh* uri = resolvePrefixToURI(prefix);
- DatatypeValidator* baseValidator = getDatatypeValidator(uri, localPart);
- if (baseValidator == 0) {
- SchemaInfo* saveInfo = fSchemaInfo;
- DOM_Element baseTypeNode =
- fSchemaInfo->getTopLevelComponent(SchemaSymbols::fgELT_SIMPLETYPE, localPart, &fSchemaInfo);
- if (baseTypeNode != 0) {
- traverseSimpleTypeDecl(baseTypeNode);
- baseValidator = getDatatypeValidator(uri, localPart);
- // restore schema information, if necessary
- fSchemaInfo = saveInfo;
- }
- }
- if (baseValidator == 0) {
- reportSchemaError(XMLUni::fgValidityDomain, XMLValid::UnknownBaseDatatype, baseTypeStr,
- getElementAttValue(rootElem, SchemaSymbols::fgATT_NAME));
- }
- else {
- int finalSet = baseValidator->getFinalSet();
- if (finalSet !=0 && ((finalSet & baseRefContext) != 0)) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DisallowedBaseDerivation, baseTypeStr);
- return 0;
- }
- }
- return baseValidator;
- }
- const XMLCh* TraverseSchema::resolvePrefixToURI(const XMLCh* const prefix) {
- int nameSpaceIndex = fNamespaceScope->getNamespaceForPrefix(prefix, fSchemaInfo->getNamespaceScopeLevel());
- const XMLCh* uriStr = fURIStringPool->getValueForId(nameSpaceIndex);
- if (!XMLString::stringLen(uriStr) && XMLString::stringLen(prefix)) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::UnresolvedPrefix, prefix);
- return XMLUni::fgZeroLenString;
- }
- return uriStr;
- }
- const XMLCh* TraverseSchema::resolvePrefixToURI(const XMLCh* const prefix,
- const unsigned int namespaceDepth) {
- int nameSpaceIndex = fNamespaceScope->getNamespaceForPrefix(prefix, namespaceDepth);
- const XMLCh* uriStr = fURIStringPool->getValueForId(nameSpaceIndex);
- if (!XMLString::stringLen(uriStr) && XMLString::stringLen(prefix)) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::UnresolvedPrefix, prefix);
- return XMLUni::fgZeroLenString;
- }
- return uriStr;
- }
- bool TraverseSchema::isTopLevelComponent(const DOM_Element& elem) {
- DOMString parentName = elem.getParentNode().getLocalName();
- fBuffer.set(parentName.rawBuffer(), parentName.length());
- XMLCh* nameStr = fBuffer.getRawBuffer();
- return (XMLString::endsWith(nameStr, SchemaSymbols::fgELT_SCHEMA))
- || (XMLString::endsWith(nameStr, SchemaSymbols::fgELT_REDEFINE));
- }
- QName* TraverseSchema::processElementDeclRef(const DOM_Element& elem,
- const XMLCh* const refName,
- bool& toDelete) {
- DOM_Element content = checkContent(elem, XUtil::getFirstChildElement(elem),
- true);
- if (content != 0) {
- reportSchemaError(XMLUni::fgValidityDomain, XMLValid::NoContentForRef, SchemaSymbols::fgELT_ELEMENT);
- }
- const XMLCh* prefix = getPrefix(refName);
- const XMLCh* localPart = getLocalPart(refName);
- const XMLCh* uriStr = resolvePrefixToURI(prefix);
- QName* eltName = new QName(prefix , localPart, uriStr != 0
- ? fURIStringPool->addOrFind(uriStr)
- : fEmptyNamespaceURI); // StringPool.EMPTY_STRING == 0
- //if from another schema, just return the element QName
- if (XMLString::compareString(uriStr, fTargetNSURIString) != 0) {
- return eltName;
- }
- unsigned int uriID = eltName->getURI();
- SchemaElementDecl* refElemDecl = (SchemaElementDecl*)
- fSchemaGrammar->getElemDecl(uriID, localPart, 0, Grammar::TOP_LEVEL_SCOPE);
- //if not found, traverse the top level element that is referenced
- if (!refElemDecl) {
- SchemaInfo* saveInfo = fSchemaInfo;
- DOM_Element targetElem = fSchemaInfo->getTopLevelComponent(SchemaSymbols::fgELT_ELEMENT, localPart, &fSchemaInfo);
- if (targetElem == 0) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::RefElementNotFound, localPart);
- // REVISIT do we return 0 or what? for now we will return QName created
- return eltName;
- }
- else {
- // problems with recursive declarations
- /*
- delete eltName;
- eltName = traverseElementDecl(targetElem);
- refElemDecl = (SchemaElementDecl*)
- fSchemaGrammar->getElemDecl(uriID, localPart, 0, Grammar::TOP_LEVEL_SCOPE);
- */
- // restore schema information
- fSchemaInfo = saveInfo;
- }
- }
- if (fFullConstraintChecking) {
- toDelete = false;
- fRefElements->addElement(eltName);
- fRefElemScope->addElement(fCurrentScope);
- }
- return eltName;
- }
- int TraverseSchema::parseBlockSet(const XMLCh* const blockStr,
- const int blockType) {
- if (!XMLString::stringLen(blockStr)) {
- return fBlockDefault;
- }
- int blockSet = 0;
- if (!XMLString::compareString(blockStr, SchemaSymbols::fgATTVAL_POUNDALL)) {
- blockSet = SchemaSymbols::EXTENSION + SchemaSymbols::RESTRICTION + SchemaSymbols::SUBSTITUTION;
- return blockSet;
- }
- XMLStringTokenizer tokenizer(blockStr);
- while (tokenizer.hasMoreTokens()) {
- XMLCh* token = tokenizer.nextToken();
- if (!XMLString::compareString(token, SchemaSymbols::fgATTVAL_SUBSTITUTION)
- && blockType == ES_Block) {
- if ((blockSet & SchemaSymbols::SUBSTITUTION) == 0 ) {
- blockSet += SchemaSymbols::SUBSTITUTION;
- }
- else {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::SubstitutionRepeated);
- }
- }
- else if (!XMLString::compareString(token, SchemaSymbols::fgATTVAL_EXTENSION)) {
- if ((blockSet & SchemaSymbols::EXTENSION) == 0) {
- blockSet += SchemaSymbols::EXTENSION;
- }
- else {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::ExtensionRepeated);
- }
- }
- else if (!XMLString::compareString(token, SchemaSymbols::fgATTVAL_RESTRICTION)) {
- if ((blockSet & SchemaSymbols::RESTRICTION) == 0 ) {
- blockSet += SchemaSymbols::RESTRICTION;
- }
- else {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::RestrictionRepeated);
- }
- }
- else {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidBlockValue, blockStr);
- }
- } //end while
- return (blockSet == 0 ? fBlockDefault : blockSet);
- }
- int TraverseSchema::parseFinalSet(const XMLCh* const finalStr,
- const int finalType) {
- if (!XMLString::stringLen(finalStr)) {
- return fFinalDefault;
- }
- int finalSet = 0;
- if (!XMLString::compareString(finalStr, SchemaSymbols::fgATTVAL_POUNDALL)) {
- finalSet = SchemaSymbols::RESTRICTION + SchemaSymbols::LIST +
- SchemaSymbols::UNION + SchemaSymbols::EXTENSION;
- return finalSet;
- }
- XMLStringTokenizer tokenizer(finalStr);
- while (tokenizer.hasMoreTokens()) {
- XMLCh* token = tokenizer.nextToken();
- if (!XMLString::compareString(token, SchemaSymbols::fgELT_UNION)
- && finalType == S_Final) {
- if ((finalSet & SchemaSymbols::UNION) == 0) {
- finalSet += SchemaSymbols::UNION;
- }
- else {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::UnionRepeated);
- }
- }
- else if (!XMLString::compareString(token, SchemaSymbols::fgATTVAL_EXTENSION)
- && finalType != S_Final) {
- if ((finalSet & SchemaSymbols::EXTENSION) == 0) {
- finalSet += SchemaSymbols::EXTENSION;
- }
- else {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::ExtensionRepeated);
- }
- }
- else if (!XMLString::compareString(token, SchemaSymbols::fgELT_LIST)
- && finalType == S_Final) {
- if ((finalSet & SchemaSymbols::LIST) == 0 ) {
- finalSet += SchemaSymbols::LIST;
- }
- else {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::ListRepeated);
- }
- }
- else if (!XMLString::compareString(token, SchemaSymbols::fgATTVAL_RESTRICTION)) {
- if ((finalSet & SchemaSymbols::RESTRICTION) == 0 ) {
- finalSet += SchemaSymbols::RESTRICTION;
- }
- else {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::RestrictionRepeated);
- }
- }
- else {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidFinalValue, finalStr);
- }
- } //end while
- return (finalSet == 0 ? fFinalDefault : finalSet);
- }
- DOM_Element
- TraverseSchema::checkIdentityConstraintContent(const DOM_Element& content) {
- DOM_Element child = content;
- if (child != 0) {
- do {
- DOMString childName = child.getLocalName();
- fBuffer.set(childName.rawBuffer(), childName.length());
- if (!isIdentityConstraintName(fBuffer.getRawBuffer())) {
- break;
- }
- child = XUtil::getNextSiblingElement(child);
- } while (child != 0);
- }
- return child;
- }
- bool TraverseSchema::isIdentityConstraintName(const XMLCh* const name) {
- return (XMLString::compareString(name, SchemaSymbols::fgELT_KEY) == 0
- || XMLString::compareString(name, SchemaSymbols::fgELT_KEYREF) == 0
- || XMLString::compareString(name, SchemaSymbols::fgELT_UNIQUE) == 0);
- }
- const XMLCh*
- TraverseSchema::checkTypeFromAnotherSchema(const XMLCh* const typeStr) {
- const XMLCh* prefix = getPrefix(typeStr);
- const XMLCh* typeURI = resolvePrefixToURI(prefix);
- if (XMLString::compareString(typeURI, fTargetNSURIString) != 0
- && XMLString::compareString(typeURI,
- SchemaSymbols::fgURI_SCHEMAFORSCHEMA) != 0
- && XMLString::stringLen(typeURI) != 0) {
- return typeURI;
- }
- return 0;
- }
- DatatypeValidator*
- TraverseSchema::getElementTypeValidator(const XMLCh* const typeStr,
- bool& noErrorDetected,
- const XMLCh* const otherSchemaURI,
- bool errorCheck)
- {
- const XMLCh* localPart = getLocalPart(typeStr);
- const XMLCh* typeURI = otherSchemaURI;
- DatatypeValidator* dv = 0;
- if (otherSchemaURI != 0) {
- dv = getDatatypeValidator(typeURI, localPart);
- }
- else {
- const XMLCh* prefix = getPrefix(typeStr);
- typeURI = resolvePrefixToURI(prefix);
- dv = getDatatypeValidator(typeURI, localPart);
- if (dv == 0) {
- if (XMLString::compareString(typeURI, SchemaSymbols::fgURI_SCHEMAFORSCHEMA) != 0
- || XMLString::compareString(fTargetNSURIString, SchemaSymbols::fgURI_SCHEMAFORSCHEMA) == 0) {
- SchemaInfo* saveInfo = fSchemaInfo;
- DOM_Element elem = fSchemaInfo->getTopLevelComponent(SchemaSymbols::fgELT_SIMPLETYPE, localPart, &fSchemaInfo);
- if (elem != 0 && traverseSimpleTypeDecl(elem) != -1) {
- dv = getDatatypeValidator(typeURI, localPart);
- }
- // restore schema information
- fSchemaInfo = saveInfo;
- }
- }
- }
- if (dv == 0 && errorCheck) {
- noErrorDetected = false;
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::TypeNotFound, typeURI, localPart);
- }
- return dv;
- }
- ComplexTypeInfo*
- TraverseSchema::getElementComplexTypeInfo(const XMLCh* const typeStr,
- bool& noErrorDetected,
- const XMLCh* const otherSchemaURI)
- {
- const XMLCh* localPart = getLocalPart(typeStr);
- const XMLCh* prefix = getPrefix(typeStr);
- const XMLCh* typeURI = (otherSchemaURI) ? otherSchemaURI : resolvePrefixToURI(prefix);
- ComplexTypeInfo* typeInfo = 0;
- SchemaInfo* saveInfo = fSchemaInfo;
- SchemaInfo::ListType infoType = SchemaInfo::INCLUDE;
- fBuffer.set(typeURI);
- fBuffer.append(chComma);
- fBuffer.append(localPart);
- if (otherSchemaURI != 0) {
- Grammar* aGrammar = fGrammarResolver->getGrammar(typeURI);
- if (!aGrammar || aGrammar->getGrammarType() != Grammar::SchemaGrammarType) {
- reportSchemaError(XMLUni::fgValidityDomain, XMLValid::GrammarNotFound, typeURI);
- return 0;
- }
- typeInfo = ((SchemaGrammar*)aGrammar)->getComplexTypeRegistry()->get(fBuffer.getRawBuffer());
- if (typeInfo) {
- return typeInfo;
- }
- SchemaInfo* impInfo = fSchemaInfo->getImportInfo(fURIStringPool->addOrFind(typeURI));
- if (!impInfo) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::UnresolvedPrefix, prefix);
- noErrorDetected = false;
- return 0;
- }
- infoType = SchemaInfo::IMPORT;
- fSchemaInfo->setCurrentScope(fCurrentScope);
- fSchemaInfo->setScopeCount(fScopeCount);
- restoreSchemaInfo(impInfo, infoType);
- }
- else {
- typeInfo = fComplexTypeRegistry->get(fBuffer.getRawBuffer());
- }
- if (!typeInfo) {
- if (XMLString::compareString(typeURI, SchemaSymbols::fgURI_SCHEMAFORSCHEMA) != 0 ||
- XMLString::compareString(fTargetNSURIString, SchemaSymbols::fgURI_SCHEMAFORSCHEMA) == 0) {
- DOM_Element elem = fSchemaInfo->getTopLevelComponent(SchemaSymbols::fgELT_COMPLEXTYPE, localPart, &fSchemaInfo);
- if (elem != 0) {
- int typeIndex = traverseComplexTypeDecl(elem);
- typeInfo = fComplexTypeRegistry->get(fStringPool->getValueForId(typeIndex));
- }
- }
- }
- // restore schema information, if necessary
- if (saveInfo != fSchemaInfo) {
- restoreSchemaInfo(saveInfo, infoType);
- }
- return typeInfo;
- }
- SchemaElementDecl*
- TraverseSchema::getSubstituteGroupElemDecl(const XMLCh* const name,
- bool& noErrorDetected) {
- const XMLCh* nameURI = resolvePrefixToURI(getPrefix(name));
- const XMLCh* localPart = getLocalPart(name);
- SchemaElementDecl* elemDecl = 0;
- SchemaInfo* saveInfo = fSchemaInfo;
- SchemaInfo::ListType infoType = SchemaInfo::INCLUDE;
- if (XMLString::compareString(nameURI, fTargetNSURIString) != 0) {
- Grammar* grammar = fGrammarResolver->getGrammar(nameURI);
- unsigned int uriId = fURIStringPool->addOrFind(nameURI);
- if (grammar && grammar->getGrammarType() == Grammar::SchemaGrammarType) {
- elemDecl = (SchemaElementDecl*)
- grammar->getElemDecl(uriId, localPart, 0, Grammar::TOP_LEVEL_SCOPE);
- }
- else {
- reportSchemaError(XMLUni::fgValidityDomain, XMLValid::GrammarNotFound, nameURI);
- return 0;
- }
- if (!elemDecl) {
- SchemaInfo* impInfo = fSchemaInfo->getImportInfo(uriId);
- if (!impInfo) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::TypeNotFound, nameURI, localPart);
- return 0;
- }
- infoType = SchemaInfo::IMPORT;
- fSchemaInfo->setCurrentScope(fCurrentScope);
- fSchemaInfo->setScopeCount(fScopeCount);
- restoreSchemaInfo(impInfo, infoType);
- }
- }
- else {
- elemDecl = (SchemaElementDecl*)
- fSchemaGrammar->getElemDecl(fTargetNSURI, localPart, 0, Grammar::TOP_LEVEL_SCOPE);
- }
- if (!elemDecl) {
- DOM_Element subsGroupElem = fSchemaInfo->getTopLevelComponent(SchemaSymbols::fgELT_ELEMENT,localPart, &fSchemaInfo);
- if (subsGroupElem != 0) {
- bool toDelete = true;
- QName* subsGroupQName = traverseElementDecl(subsGroupElem, toDelete);
- Janitor<QName> janQName(subsGroupQName);
- if (subsGroupQName) {
- elemDecl = (SchemaElementDecl*) fSchemaGrammar->getElemDecl(fTargetNSURI, localPart,0, Grammar::TOP_LEVEL_SCOPE);
- }
- if (!elemDecl) {
- noErrorDetected = false;
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::TypeNotFound, nameURI, localPart);
- }
- }
- else {
- noErrorDetected = false;
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::TypeNotFound, nameURI, localPart);
- }
- }
- // restore schema information, if necessary
- if (saveInfo != fSchemaInfo) {
- restoreSchemaInfo(saveInfo, infoType);
- }
- return elemDecl;
- }
- bool
- TraverseSchema::isSubstitutionGroupValid(const SchemaElementDecl* const subsElemDecl,
- const ComplexTypeInfo* const typeInfo,
- const DatatypeValidator* const validator,
- const XMLCh* const elemName,
- const bool toEmit) {
- // here we must do two things:
- // 1. Make sure there actually *is* a relation between the types of
- // the element being nominated and the element doing the nominating;
- // (see PR 3.3.6 point #3 in the first tableau, for instance; this
- // and the corresponding tableaux from 3.4.6 and 3.14.6 rule out the nominated
- // element having an anonymous type declaration.
- // 2. Make sure the nominated element allows itself to be nominated by
- // an element with the given type-relation.
- // Note: we assume that (complex|simple)Type processing checks
- // whether the type in question allows itself to
- // be modified as this element desires.
- // if substitution element has any as content model type, return true
- if (subsElemDecl->getModelType() == SchemaElementDecl::Any) {
- return true;
- }
- bool subsRestricted = false;
- // Check for type relationship;
- // that is, make sure that the type we're deriving has some relatoinship
- // to substitutionGroupElt's type.
- if (typeInfo) { // do complexType case ...need testing
- int derivationMethod = typeInfo->getDerivedBy();
- if (typeInfo->getContentType() == SchemaElementDecl::Simple) { // take care of complexType based on simpleType case...
- DatatypeValidator* elemDV = typeInfo->getDatatypeValidator();
- DatatypeValidator* subsValidator = subsElemDecl->getDatatypeValidator();
- if (subsValidator && subsValidator->isSubstitutableBy(elemDV)) {
- if ((subsElemDecl->getFinalSet() & derivationMethod) == 0) {
- return true;
- }
- else {
- subsRestricted = true;
- }
- }
- }
- else { // complex content
- ComplexTypeInfo* subsTypeInfo = subsElemDecl->getComplexTypeInfo();
- const ComplexTypeInfo* elemTypeInfo = typeInfo;
- for (; elemTypeInfo && elemTypeInfo != subsTypeInfo;
- elemTypeInfo = elemTypeInfo->getBaseComplexTypeInfo()) {
- }
- if (elemTypeInfo) {
- if ((subsElemDecl->getFinalSet() & derivationMethod) == 0) {
- return true;
- }
- else {
- subsRestricted = true;
- }
- }
- }
- }
- else if (validator) { // do simpleType case...
- // first, check for type relation.
- DatatypeValidator* subsValidator = subsElemDecl->getDatatypeValidator();
- if (subsValidator && subsValidator->isSubstitutableBy(validator)
- && ((subsElemDecl->getFinalSet() & SchemaSymbols::RESTRICTION) == 0)) {
- return true;
- }
- }
- if (toEmit) {
- if (subsRestricted) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidSubstitutionGroupElement,
- elemName, subsElemDecl->getBaseName());
- }
- else {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::SubstitutionGroupTypeMismatch, elemName);
- }
- }
- return false;
- }
- SchemaElementDecl*
- TraverseSchema::createSchemaElementDecl(const DOM_Element& elem,
- const bool topLevel,
- const unsigned short elemType,
- bool& isDuplicate,
- const bool isFixedVal)
- {
- const XMLCh* name = getElementAttValue(elem, SchemaSymbols::fgATT_NAME);
- const XMLCh* elemForm = getElementAttValue(elem, SchemaSymbols::fgATT_FORM);
- int enclosingScope = fCurrentScope;
- int uriIndex = fEmptyNamespaceURI;
- //refer to 4.3.2 in "XML Schema Part 1: Structures"
- if (topLevel) {
- uriIndex = fTargetNSURI;
- enclosingScope = Grammar::TOP_LEVEL_SCOPE;
- }
- else if ((XMLString::stringLen(elemForm) == 0 &&
- (fSchemaInfo->getElemAttrDefaultQualified() & Elem_Def_Qualified))
- || XMLString::compareString(elemForm,SchemaSymbols::fgATTVAL_QUALIFIED) == 0) {
- uriIndex = fTargetNSURI;
- }
- // Check for duplicate elements
- SchemaElementDecl* other = (SchemaElementDecl*)
- fSchemaGrammar->getElemDecl(uriIndex, name, 0, enclosingScope);
- if (other != 0) {
- isDuplicate = true;
- return other;
- }
- const XMLCh* block = getElementAttValue(elem,SchemaSymbols::fgATT_BLOCK);
- const XMLCh* final = getElementAttValue(elem,SchemaSymbols::fgATT_FINAL);
- int blockSet = parseBlockSet(block, ES_Block);
- int finalSet = parseFinalSet(final, EC_Final);
- int elementMiscFlags = 0;
- const XMLCh* nillable = getElementAttValue(elem, SchemaSymbols::fgATT_NILLABLE);
- const XMLCh* abstract = getElementAttValue(elem, SchemaSymbols::fgATT_ABSTRACT);
- if (XMLString::stringLen(nillable)) {
- if (!XMLString::compareString(nillable, SchemaSymbols::fgATTVAL_TRUE)
- || !XMLString::compareString(nillable, fgValueOne)) {
- elementMiscFlags += SchemaSymbols::NILLABLE;
- }
- }
- if (XMLString::stringLen(abstract)) {
- if (!XMLString::compareString(abstract, SchemaSymbols::fgATTVAL_TRUE)
- || !XMLString::compareString(abstract, fgValueOne)) {
- elementMiscFlags += SchemaSymbols::ABSTRACT;
- }
- }
- if (isFixedVal) {
- elementMiscFlags += SchemaSymbols::FIXED;
- }
- const XMLCh* prefix = getPrefix(name);
- SchemaElementDecl* elemDecl =
- new SchemaElementDecl(prefix, name, uriIndex,
- (SchemaElementDecl::ModelTypes) elemType,
- enclosingScope);
- elemDecl->setFinalSet(finalSet);
- elemDecl->setBlockSet(blockSet);
- elemDecl->setMiscFlags(elementMiscFlags);
- elemDecl->setCreateReason(XMLElementDecl::Declared);
- return elemDecl;
- }
- void TraverseSchema::processAttributeDeclRef(const DOM_Element& elem,
- ComplexTypeInfo* const typeInfo,
- const XMLCh* const refName,
- const XMLCh* const useAttr,
- const XMLCh* const defaultVal,
- const XMLCh* const fixedVal) {
- if (!typeInfo && !fCurrentAttGroupInfo) {
- return;
- }
- const XMLCh* prefix = getPrefix(refName);
- const XMLCh* localPart = getLocalPart(refName);
- const XMLCh* uriStr = resolvePrefixToURI(prefix);
- unsigned int attURI = fURIStringPool->addOrFind(uriStr);
- // Check for duplicate references
- if (typeInfo && typeInfo->getAttDef(localPart, attURI)) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateRefAttribute, uriStr, localPart);
- return;
- }
- else if (fCurrentAttGroupInfo && fCurrentAttGroupInfo->containsAttribute(localPart, attURI)) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateRefAttribute, uriStr, localPart);
- return;
- }
- // check for different namespace
- SchemaInfo* saveInfo = fSchemaInfo;
- SchemaInfo::ListType infoType = SchemaInfo::INCLUDE;
- if (XMLString::compareString(uriStr, fTargetNSURIString) != 0) {
- SchemaInfo* impInfo = fSchemaInfo->getImportInfo(attURI);
- if (!impInfo) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::TopLevelAttributeNotFound, refName);
- return;
- }
- infoType = SchemaInfo::IMPORT;
- fSchemaInfo->setCurrentScope(fCurrentScope);
- fSchemaInfo->setScopeCount(fScopeCount);
- restoreSchemaInfo(impInfo, infoType);
- }
- // if Global attribute registry does not contain the ref attribute, get
- // the referred attribute declaration and traverse it.
- if (fAttributeDeclRegistry->containsKey(localPart) == false) {
- DOM_Element referredAttribute =
- fSchemaInfo->getTopLevelComponent(SchemaSymbols::fgELT_ATTRIBUTE, localPart, &fSchemaInfo);
- if (referredAttribute != 0) {
- traverseAttributeDecl(referredAttribute, 0);
- }
- }
- SchemaAttDef* refAttDef = (SchemaAttDef*) fAttributeDeclRegistry->get(localPart);
- // restore schema information, if necessary
- if (fSchemaInfo != saveInfo) {
- restoreSchemaInfo(saveInfo, infoType);
- }
- if (!refAttDef) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::TopLevelAttributeNotFound, refName);
- return;
- }
- XMLAttDef::DefAttTypes refAttDefType = refAttDef->getDefaultType();
- const XMLCh* refAttValue = refAttDef->getValue();
- bool invalidAttUse = false;
- if (refAttDefType == XMLAttDef::Fixed &&
- (defaultVal || (fixedVal && XMLString::compareString(fixedVal, refAttValue)))) {
- invalidAttUse = true;
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::AttUseCorrect, refName);
- }
- DatatypeValidator* attDV = refAttDef->getDatatypeValidator();
- //check for multiple attributes with type derived from ID
- if (attDV && attDV->getType() == DatatypeValidator::ID) {
- if (fCurrentAttGroupInfo) {
- if (fCurrentAttGroupInfo->containsTypeWithId()) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::AttGrpPropCorrect3, refName);
- return;
- }
- fCurrentAttGroupInfo->setTypeWithId(true);
- }
- else {
- if (typeInfo->containsAttWithTypeId()) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::AttDeclPropCorrect5, refName);
- return;
- }
- typeInfo->setAttWithTypeId(true);
- }
- }
- bool required = (XMLString::compareString(useAttr,SchemaSymbols::fgATTVAL_REQUIRED) == 0);
- bool prohibited = (XMLString::compareString(useAttr,SchemaSymbols::fgATTVAL_PROHIBITED) == 0);
- QName* attQName = refAttDef->getAttName();
- SchemaAttDef* attDef = new SchemaAttDef(attQName->getPrefix(),
- attQName->getLocalPart(),
- attQName->getURI(),
- refAttValue,
- refAttDef->getType(),
- refAttDefType);
- if (refAttDefType == XMLAttDef::Fixed) {
- if (required && !invalidAttUse) {
- attDef->setDefaultType(XMLAttDef::Required_And_Fixed);
- }
- }
- else {
- if (prohibited) {
- attDef->setDefaultType(XMLAttDef::Prohibited);
- }
- else {
- const XMLCh* valueConstraint = defaultVal;
- if (required){
- if (fixedVal) {
- attDef->setDefaultType(XMLAttDef::Required_And_Fixed);
- valueConstraint = fixedVal;
- }
- else {
- attDef->setDefaultType(XMLAttDef::Required);
- }
- }
- if (valueConstraint) {
- // validate content of value constraint
- if (attDV) {
- if (attDV->getType() == DatatypeValidator::ID) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::AttDeclPropCorrect3,
- SchemaSymbols::fgATT_REF, refName);
- }
- else {
- try {
- attDV->validate(valueConstraint);
- }
- catch(const XMLException& excep) {
- reportSchemaError(XMLUni::fgValidityDomain, XMLValid::DisplayErrorMessage, excep.getMessage());
- }
- catch (...) {
- reportSchemaError(XMLUni::fgValidityDomain, XMLValid::DatatypeValidationFailure, valueConstraint);
- }
- }
- }
- attDef->setValue(valueConstraint);
- }
- }
- }
- attDef->setDatatypeValidator(attDV);
- bool toClone = false;
- if (typeInfo) {
- toClone = true;
- typeInfo->addAttDef(attDef);
- }
- if (fCurrentAttGroupInfo) {
- fCurrentAttGroupInfo->addAttDef(attDef, toClone);
- }
- }
- void TraverseSchema::checkMinMax(ContentSpecNode* const specNode,
- const DOM_Element& elem,
- const int allContextFlag) {
- unsigned int minOccurs = 0;
- unsigned int maxOccurs = 0;
- const XMLCh* minOccursStr =
- getElementAttValue(elem, SchemaSymbols::fgATT_MINOCCURS, true);
- const XMLCh* maxOccursStr =
- getElementAttValue(elem, SchemaSymbols::fgATT_MAXOCCURS, true);
- if (XMLString::stringLen(minOccursStr) == 0) {
- if (specNode)
- minOccurs = specNode->getMinOccurs();
- else
- minOccurs = 1;
- }
- else {
- XMLString::textToBin(minOccursStr, minOccurs);
- if (specNode)
- specNode->setMinOccurs(minOccurs);
- }
- bool isMaxUnbounded =
- (XMLString::compareString(maxOccursStr, fgUnbounded) == 0);
- if (isMaxUnbounded) {
- maxOccurs = SchemaSymbols::UNBOUNDED;
- if (specNode)
- specNode->setMaxOccurs(maxOccurs);
- }
- else {
- if (XMLString::stringLen(maxOccursStr) == 0) {
- if (specNode)
- maxOccurs = specNode->getMaxOccurs();
- else
- maxOccurs = 1;
- }
- else {
- XMLString::textToBin(maxOccursStr, maxOccurs);
- if (specNode)
- specNode->setMaxOccurs(maxOccurs);
- }
- }
- // Constraint checking for min/max value
- if (!isMaxUnbounded) {
- XMLCh tmpMinStr[128];
- XMLCh tmpMaxStr[128];
- XMLString::binToText(minOccurs, tmpMinStr, 127, 10);
- XMLString::binToText(maxOccurs, tmpMaxStr, 127, 10);
- if (maxOccurs < 1) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidAttValue,
- tmpMaxStr, SchemaSymbols::fgATT_MAXOCCURS);
- if (specNode)
- specNode->setMaxOccurs(minOccurs);
- }
- else if (maxOccurs < minOccurs) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidMin2MaxOccurs,
- tmpMinStr, tmpMaxStr);
- if (specNode)
- specNode->setMaxOccurs(minOccurs);
- }
- }
- if (minOccurs == 0 && maxOccurs == 0){
- return;
- }
- // Constraint checking for 'all' content
- bool isAllElement = (allContextFlag == All_Element);
- bool isAllGroup = (allContextFlag == All_Group);
- bool isGroupRefAll = (allContextFlag == Group_Ref_With_All);
- if (isAllElement || isAllGroup || isGroupRefAll) {
- if (maxOccurs != 1
- || ((isAllGroup || isGroupRefAll || minOccurs != 0)
- && minOccurs != 1)) {
- // set back correct value in order to carry on
- if (specNode) {
- specNode->setMaxOccurs(1);
- if (isAllGroup || isGroupRefAll)
- specNode->setMinOccurs(1);
- else
- specNode->setMinOccurs(0);
- }
- if (isAllElement) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadMinMaxAllElem);
- }
- else {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadMinMaxAllCT);
- }
- }
- }
- }
- void TraverseSchema::processComplexContent(const XMLCh* const typeName,
- const DOM_Element& childElem,
- ComplexTypeInfo* const typeInfo,
- const XMLCh* const baseRawName,
- const XMLCh* const baseLocalPart,
- const XMLCh* const baseURI,
- const bool isMixed,
- const bool isBaseAnyType) {
- ContentSpecNode* specNode = 0;
- DOM_Element attrNode;
- int typeDerivedBy = SchemaSymbols::EMPTY_SET;
- ComplexTypeInfo* baseTypeInfo = typeInfo->getBaseComplexTypeInfo();
- if (baseTypeInfo) {
- if (typeInfo->getDerivedBy() == SchemaSymbols::RESTRICTION) {
- typeDerivedBy = SchemaSymbols::RESTRICTION;
- // check to see if the baseType permits derivation by restriction
- if((baseTypeInfo->getFinalSet() & typeDerivedBy) != 0) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::ForbiddenDerivationByRestriction,
- baseLocalPart);
- throw TraverseSchema::InvalidComplexTypeInfo;
- }
- }
- else {
- typeDerivedBy = SchemaSymbols::EXTENSION;
- // check to see if the baseType permits derivation by extension
- if((baseTypeInfo->getFinalSet() & typeDerivedBy) != 0) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::ForbiddenDerivationByExtension, baseLocalPart);
- throw TraverseSchema::InvalidComplexTypeInfo; // REVISIT - should we continue
- }
- // Check for derivation valid (extension) - 1.4.2.2
- int baseContentType = baseTypeInfo->getContentType();
- if (baseContentType != SchemaElementDecl::Empty) {
- if ((isMixed && baseContentType == SchemaElementDecl::Children)
- || (!isMixed && baseContentType == SchemaElementDecl::Mixed_Complex)) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::MixedOrElementOnly, baseLocalPart, typeName);
- throw TraverseSchema::InvalidComplexTypeInfo; //REVISIT - should we continue
- }
- }
- processElements(baseTypeInfo, typeInfo);
- }
- }
- if (childElem != 0) {
- // --------------------------------------------------------------------
- // GROUP, ALL, SEQUENCE or CHOICE, followed by attributes, if specified.
- // Note that it's possible that only attributes are specified.
- // --------------------------------------------------------------------
- DOMString childName = childElem.getLocalName();
- if (childName.equals(SchemaSymbols::fgELT_GROUP)) {
- XercesGroupInfo* grpInfo = traverseGroupDecl(childElem);
- if (grpInfo) {
- specNode = grpInfo->getContentSpec();
- if (specNode) {
- int contentContext = hasAllContent(specNode) ? Group_Ref_With_All : Not_All_Context;
- specNode = new ContentSpecNode(*specNode);
- checkMinMax(specNode, childElem, contentContext);
- }
- }
- attrNode = XUtil::getNextSiblingElement(childElem);
- }
- else if (childName.equals(SchemaSymbols::fgELT_SEQUENCE)) {
- specNode = traverseChoiceSequence(childElem, ContentSpecNode::Sequence);
- checkMinMax(specNode, childElem);
- attrNode = XUtil::getNextSiblingElement(childElem);
- }
- else if (childName.equals(SchemaSymbols::fgELT_CHOICE)) {
- specNode = traverseChoiceSequence(childElem, ContentSpecNode::Choice);
- checkMinMax(specNode, childElem);
- attrNode = XUtil::getNextSiblingElement(childElem);
- }
- else if (childName.equals(SchemaSymbols::fgELT_ALL)) {
- specNode = traverseAll(childElem);
- checkMinMax(specNode, childElem, All_Group);
- attrNode = XUtil::getNextSiblingElement(childElem);
- }
- else if (isAttrOrAttrGroup(childElem)) {
- // reset the contentType
- typeInfo->setContentType(SchemaElementDecl::Any);
- attrNode = childElem;
- }
- else {
- fBuffer.set(childName.rawBuffer(), childName.length());
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidChildInComplexType,
- fBuffer.getRawBuffer());
- }
- }
- typeInfo->setContentSpec(specNode);
- typeInfo->setAdoptContentSpec(true);
- // -----------------------------------------------------------------------
- // Merge in information from base, if it exists
- // -----------------------------------------------------------------------
- if (baseTypeInfo != 0) {
- ContentSpecNode* baseSpecNode = baseTypeInfo->getContentSpec();
- if (typeDerivedBy == SchemaSymbols::RESTRICTION) {
- //check derivation valid - content type is empty (5.2)
- if (!typeInfo->getContentSpec()) {
- if (baseTypeInfo->getContentType() != SchemaElementDecl::Empty
- && !emptiableParticle(baseSpecNode)) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::EmptyComplexRestrictionDerivation);
- }
- }
- else { // if base has no content spec, invalid derivation
- if (!baseTypeInfo->getContentSpec()) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::PD_EmptyBase);
- throw TraverseSchema::InvalidComplexTypeInfo; //REVISIT - should we continue
- }
- }
- // Delay particle constraint checking (5.3) until we have processed
- // the whole schema.
- }
- else {
- // Compose the final content model by concatenating the base and
- // the current in sequence
- if (!specNode) {
- if (baseSpecNode) {
- specNode = new ContentSpecNode(*baseSpecNode);
- typeInfo->setContentSpec(specNode);
- typeInfo->setAdoptContentSpec(true);
- }
- }
- else if (baseSpecNode != 0) {
- typeInfo->setAdoptContentSpec(false);
- typeInfo->setContentSpec(
- new ContentSpecNode(ContentSpecNode::Sequence,
- new ContentSpecNode(*baseSpecNode),
- specNode));
- typeInfo->setAdoptContentSpec(true);
- }
- }
- }
- else {
- if (isBaseAnyType) {
- QName elemName(XMLUni::fgZeroLenString, XMLUni::fgZeroLenString, fEmptyNamespaceURI);
- specNode = new ContentSpecNode(&elemName);
- specNode->setType(ContentSpecNode::Any);
- specNode->setMinOccurs(0);
- specNode->setMaxOccurs(SchemaSymbols::UNBOUNDED);
- typeInfo->setContentSpec(specNode);
- }
- typeInfo->setDerivedBy(0);
- }
- // -------------------------------------------------------------
- // Set the content type
- // -------------------------------------------------------------
- if (isMixed) {
- if (specNode != 0) {
- typeInfo->setContentType(SchemaElementDecl::Mixed_Complex);
- }
- else {
- // add #PCDATA leaf and set its minOccurs to 0
- ContentSpecNode* pcdataNode =
- new ContentSpecNode(new QName(XMLUni::fgZeroLenString,
- XMLUni::fgZeroLenString,
- XMLElementDecl::fgPCDataElemId),
- false);
- pcdataNode->setMinOccurs(0);
- typeInfo->setContentSpec(pcdataNode);
- typeInfo->setAdoptContentSpec(true);
- typeInfo->setContentType(SchemaElementDecl::Mixed_Simple);
- }
- }
- else if (typeInfo->getContentSpec() == 0) {
- typeInfo->setContentType(SchemaElementDecl::Empty);
- }
- else {
- typeInfo->setContentType(SchemaElementDecl::Children);
- }
- // -------------------------------------------------------------
- // Now, check attributes and handle
- // -------------------------------------------------------------
- if (attrNode != 0) {
- if (!isAttrOrAttrGroup(attrNode)) {
- fBuffer.set(attrNode.getLocalName().rawBuffer(),
- attrNode.getLocalName().length());
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidChildInComplexType,
- fBuffer.getRawBuffer());
- }
- else {
- processAttributes(attrNode, baseRawName, baseLocalPart,
- baseURI, typeInfo);
- }
- }
- else if (baseTypeInfo != 0) {
- processAttributes(0, baseRawName, baseLocalPart, baseURI, typeInfo);
- }
- }
- void TraverseSchema::processBaseTypeInfo(const XMLCh* const baseName,
- const XMLCh* const localPart,
- const XMLCh* const uriStr,
- ComplexTypeInfo* const typeInfo) {
- SchemaInfo* saveInfo = fSchemaInfo;
- ComplexTypeInfo* baseComplexTypeInfo = 0;
- DatatypeValidator* baseDTValidator = 0;
- SchemaInfo::ListType infoType = SchemaInfo::INCLUDE;
- // -------------------------------------------------------------
- // check if the base type is from another schema
- // -------------------------------------------------------------
- if (isBaseFromAnotherSchema(uriStr)) {
- baseComplexTypeInfo = getTypeInfoFromNS(uriStr, localPart);
- if (!baseComplexTypeInfo) {
- SchemaInfo* impInfo = fSchemaInfo->getImportInfo(fURIStringPool->addOrFind(uriStr));
- if (!impInfo) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BaseTypeNotFound, baseName);
- throw TraverseSchema::InvalidComplexTypeInfo;
- }
- infoType = SchemaInfo::IMPORT;
- fSchemaInfo->setCurrentScope(fCurrentScope);
- fSchemaInfo->setScopeCount(fScopeCount);
- restoreSchemaInfo(impInfo, infoType);
- }
- }
- else {
- fBuffer.set(uriStr);
- fBuffer.append(chComma);
- fBuffer.append(localPart);
- // assume the base is a complexType and try to locate the base type first
- const XMLCh* fullBaseName = fBuffer.getRawBuffer();
- baseComplexTypeInfo = fComplexTypeRegistry->get(fullBaseName);
- // Circular check
- if (baseComplexTypeInfo &&
- fCurrentTypeNameStack->containsElement(fStringPool->addOrFind(fullBaseName))) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::NoCircularDefinition, fullBaseName);
- throw TraverseSchema::InvalidComplexTypeInfo;
- }
- }
- // if not found, 2 possibilities:
- // 1: ComplexType in question has not been compiled yet;
- // 2: base is SimpleTYpe;
- if (!baseComplexTypeInfo) {
- baseDTValidator = getDatatypeValidator(uriStr, localPart);
- if (baseDTValidator == 0) {
- DOM_Element baseTypeNode =
- fSchemaInfo->getTopLevelComponent(SchemaSymbols::fgELT_COMPLEXTYPE, localPart, &fSchemaInfo);
- if (baseTypeNode != 0) {
- int baseTypeSymbol = traverseComplexTypeDecl(baseTypeNode);
- baseComplexTypeInfo = fComplexTypeRegistry->get(fStringPool->getValueForId(baseTypeSymbol));
- }
- else {
- baseTypeNode = fSchemaInfo->getTopLevelComponent(SchemaSymbols::fgELT_SIMPLETYPE, localPart, &fSchemaInfo);
- if (baseTypeNode != 0) {
- int baseTypeSymbol = traverseSimpleTypeDecl(baseTypeNode);
- baseDTValidator = getDatatypeValidator(uriStr, localPart);
- if (baseDTValidator == 0) {
- // restore schema information, if necessary
- if (saveInfo != fSchemaInfo) {
- restoreSchemaInfo(saveInfo, infoType);
- }
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::TypeNotFound, uriStr, localPart, uriStr);
- throw TraverseSchema::InvalidComplexTypeInfo;
- }
- }
- else {
- // restore schema information, if necessary
- if (saveInfo != fSchemaInfo) {
- restoreSchemaInfo(saveInfo, infoType);
- }
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BaseTypeNotFound, baseName);
- throw TraverseSchema::InvalidComplexTypeInfo;
- }
- }
- }
- } // end if
- // restore schema information, if necessary
- if (saveInfo != fSchemaInfo) {
- restoreSchemaInfo(saveInfo, infoType);
- }
- typeInfo->setBaseComplexTypeInfo(baseComplexTypeInfo);
- typeInfo->setBaseDatatypeValidator(baseDTValidator);
- }
- ComplexTypeInfo* TraverseSchema::getTypeInfoFromNS(const XMLCh* const uriStr,
- const XMLCh* const localPart)
- {
- Grammar* grammar = fGrammarResolver->getGrammar(uriStr);
- if (grammar != 0 && grammar->getGrammarType() == Grammar::SchemaGrammarType) {
- fBuffer.set(uriStr);
- fBuffer.append(chComma);
- fBuffer.append(localPart);
- ComplexTypeInfo* typeInfo =
- ((SchemaGrammar*)grammar)->getComplexTypeRegistry()->get(fBuffer.getRawBuffer());
- return typeInfo;
- }
- else {
- reportSchemaError(XMLUni::fgValidityDomain, XMLValid::GrammarNotFound, uriStr);
- }
- return 0;
- }
- bool TraverseSchema::isValidFacet(const XMLCh* const component,
- const XMLCh* const name) {
- if (!XMLString::compareString(name, SchemaSymbols::fgELT_MINEXCLUSIVE) ||
- !XMLString::compareString(name, SchemaSymbols::fgELT_MININCLUSIVE) ||
- !XMLString::compareString(name, SchemaSymbols::fgELT_MAXEXCLUSIVE) ||
- !XMLString::compareString(name, SchemaSymbols::fgELT_MAXINCLUSIVE) ||
- !XMLString::compareString(name, SchemaSymbols::fgELT_TOTALDIGITS) ||
- !XMLString::compareString(name, SchemaSymbols::fgELT_FRACTIONDIGITS) ||
- !XMLString::compareString(name, SchemaSymbols::fgELT_LENGTH) ||
- !XMLString::compareString(name, SchemaSymbols::fgELT_MINLENGTH) ||
- !XMLString::compareString(name, SchemaSymbols::fgELT_MAXLENGTH) ||
- !XMLString::compareString(name, SchemaSymbols::fgELT_ENUMERATION) ||
- !XMLString::compareString(name, SchemaSymbols::fgELT_WHITESPACE) ||
- !XMLString::compareString(name, SchemaSymbols::fgELT_PATTERN) ||
- !XMLString::compareString(name, SchemaSymbols::fgELT_ANNOTATION)) {
- return true;
- }
- return false;
- }
- void TraverseSchema::processAttributes(const DOM_Element& attElem,
- const XMLCh* const baseRawName,
- const XMLCh* const baseLocalPart,
- const XMLCh* const baseURI,
- ComplexTypeInfo* const typeInfo) {
- // If we do not have a complexTypeInfo, then what is the point of
- // processing.
- if (typeInfo == 0) {
- return;
- }
- DOM_Element child = attElem;
- SchemaAttDef* attWildCard = 0;
- Janitor<SchemaAttDef> janAttWildCard(0);
- XercesAttGroupInfo* attGroupInfo = 0;
- ValueVectorOf<XercesAttGroupInfo*> attGroupList(4);
- for (; child != 0; child = XUtil::getNextSiblingElement(child)) {
- DOMString childName = child.getLocalName();
- if (childName.equals(SchemaSymbols::fgELT_ATTRIBUTE)) {
- traverseAttributeDecl(child, typeInfo);
- }
- else if (childName.equals(SchemaSymbols::fgELT_ATTRIBUTEGROUP)) {
- attGroupInfo = traverseAttributeGroupDecl(child, typeInfo);
- if (attGroupInfo && !attGroupList.containsElement(attGroupInfo)) {
- attGroupList.addElement(attGroupInfo);
- }
- }
- else if (childName.equals(SchemaSymbols::fgELT_ANYATTRIBUTE) ) {
- attWildCard = traverseAnyAttribute(child);
- janAttWildCard.reset(attWildCard);
- }
- else {
- fBuffer.set(childName.rawBuffer(), childName.length());
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidChildInComplexType,
- fBuffer.getRawBuffer());
- }
- }
- // -------------------------------------------------------------
- // Handle wild card/any attribute
- // -------------------------------------------------------------
- ComplexTypeInfo* baseTypeInfo = typeInfo->getBaseComplexTypeInfo();
- SchemaAttDef* baseAttWildCard = (baseTypeInfo) ? baseTypeInfo->getAttWildCard() : 0;
- int derivedBy = typeInfo->getDerivedBy();
- unsigned int attGroupListSize = attGroupList.size();
- if (attGroupListSize) {
- SchemaAttDef* completeWildCard = 0;
- Janitor<SchemaAttDef> janCompleteWildCard(0);
- XMLAttDef::DefAttTypes defAttType;
- bool defAttTypeSet = false;
- for (unsigned int i=0; i < attGroupListSize; i++) {
- attGroupInfo = attGroupList.elementAt(i);
- unsigned int anyAttCount = attGroupInfo->anyAttributeCount();
- if (anyAttCount) {
- if (!defAttTypeSet) {
- defAttType = (attWildCard) ? attWildCard->getDefaultType()
- : attGroupInfo->anyAttributeAt(0)->getDefaultType();
- defAttTypeSet = true;
- }
- SchemaAttDef* attGroupWildCard = attGroupInfo->getCompleteWildCard();
- if (!attGroupWildCard) {
- attGroupWildCard = new SchemaAttDef(attGroupInfo->anyAttributeAt(0));
- for (unsigned int i= 1; i < anyAttCount; i++) {
- attWildCardIntersection(attGroupWildCard, attGroupInfo->anyAttributeAt(i));
- }
- attGroupInfo->setCompleteWildCard(attGroupWildCard);
- }
- if (completeWildCard) {
- attWildCardIntersection(completeWildCard, attGroupWildCard);
- }
- else {
- completeWildCard = new SchemaAttDef(attGroupWildCard);
- janCompleteWildCard.reset(completeWildCard);
- }
- }
- }
- if (completeWildCard) {
- if (attWildCard) {
- attWildCardIntersection(attWildCard, completeWildCard);
- }
- else {
- attWildCard = completeWildCard;
- janCompleteWildCard.orphan();
- janAttWildCard.reset(attWildCard);
- }
- attWildCard->setDefaultType(defAttType);
- }
- }
- if (derivedBy == SchemaSymbols::EXTENSION && baseAttWildCard && attWildCard) {
- XMLAttDef::DefAttTypes saveDefType = attWildCard->getDefaultType();
- attWildCardUnion(attWildCard, baseAttWildCard);
- attWildCard->setDefaultType(saveDefType);
- }
- // -------------------------------------------------------------
- // insert wildcard attribute
- // -------------------------------------------------------------
- if (attWildCard) {
- typeInfo->setAttWildCard(attWildCard);
- janAttWildCard.orphan();
- if (attWildCard->getType() == XMLAttDef::AttTypes_Unknown) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::NotExpressibleWildCardIntersection);
- }
- }
- else if (baseAttWildCard && derivedBy == SchemaSymbols::EXTENSION) {
- SchemaAttDef* newWildCard = new SchemaAttDef(baseAttWildCard);
- typeInfo->setAttWildCard(newWildCard);
- }
- // -------------------------------------------------------------
- // Check attributes derivation OK
- // -------------------------------------------------------------
- bool baseWithAttributes = (baseTypeInfo && baseTypeInfo->hasAttDefs());
- bool childWithAttributes = (typeInfo->hasAttDefs() || typeInfo->getAttWildCard());
- if (derivedBy == SchemaSymbols::RESTRICTION && childWithAttributes) {
- if (!baseWithAttributes && !baseAttWildCard) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_1);
- }
- else {
- checkAttDerivationOK(baseTypeInfo, typeInfo);
- }
- }
- // -------------------------------------------------------------
- // merge in base type's attribute decls
- // -------------------------------------------------------------
- if (baseTypeInfo && baseTypeInfo->hasAttDefs()) {
- SchemaAttDefList& baseAttList = (SchemaAttDefList&)
- baseTypeInfo->getAttDefList();
- while (baseAttList.hasMoreElements()) {
- SchemaAttDef& attDef = (SchemaAttDef&) baseAttList.nextElement();
- QName* attName = attDef.getAttName();
- const XMLCh* localPart = attName->getLocalPart();
- // if found a duplicate, then skip the one from the base type
- if (typeInfo->getAttDef(localPart, attName->getURI()) != 0) {
- if (derivedBy == SchemaSymbols::EXTENSION) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateAttInDerivation, localPart);
- }
- continue;
- }
- if (attDef.getDefaultType() != XMLAttDef::Prohibited) {
- SchemaAttDef* newAttDef = new SchemaAttDef(attName->getPrefix(),
- attName->getLocalPart(),
- attName->getURI(),
- attDef.getValue(),
- attDef.getType(),
- attDef.getDefaultType(),
- attDef.getEnumeration());
- newAttDef->setDatatypeValidator(attDef.getDatatypeValidator());
- typeInfo->addAttDef(newAttDef);
- }
- }
- }
- }
- void TraverseSchema::defaultComplexTypeInfo(ComplexTypeInfo* const typeInfo) {
- if (typeInfo) {
- typeInfo->setDerivedBy(0);
- typeInfo->setContentType(SchemaElementDecl::Any);
- typeInfo->setDatatypeValidator(0);
- typeInfo->setContentSpec(0);
- typeInfo->setBaseComplexTypeInfo(0);
- typeInfo->setBaseDatatypeValidator(0);
- }
- }
- InputSource* TraverseSchema::resolveSchemaLocation(const XMLCh* const loc) {
- // ------------------------------------------------------------------
- // Create an input source
- // ------------------------------------------------------------------
- InputSource* srcToFill = 0;
- if (fEntityResolver){
- srcToFill = fEntityResolver->resolveEntity(XMLUni::fgZeroLenString,
- loc);
- }
- // If they didn't create a source via the entity resolver, then we
- // have to create one on our own.
- if (!srcToFill) {
- try {
- XMLURL urlTmp(fSchemaInfo->getCurrentSchemaURL(), loc);
- if (urlTmp.isRelative()) {
- ThrowXML(MalformedURLException,
- XMLExcepts::URL_NoProtocolPresent);
- }
- srcToFill = new URLInputSource(urlTmp);
- }
- catch(const MalformedURLException&) {
- // Its not a URL, so lets assume its a local file name.
- srcToFill = new LocalFileInputSource(fSchemaInfo->getCurrentSchemaURL(),loc);
- }
- }
- return srcToFill;
- }
- void TraverseSchema::restoreSchemaInfo(SchemaInfo* const toRestore,
- SchemaInfo::ListType const aListType) {
- if (aListType == SchemaInfo::IMPORT) { // restore grammar info
- int targetNSURI = toRestore->getTargetNSURI();
- fSchemaGrammar = (SchemaGrammar*) fGrammarResolver->getGrammar(toRestore->getTargetNSURIString());
- if (!fSchemaGrammar) {
- reportSchemaError(XMLUni::fgValidityDomain, XMLValid::GrammarNotFound, fURIStringPool->getValueForId(targetNSURI));
- return;
- }
- fTargetNSURI = targetNSURI;
- fCurrentScope = toRestore->getCurrentScope();
- fScopeCount = toRestore->getScopeCount();
- fTargetNSURIString = fSchemaGrammar->getTargetNamespace();
- fGroupRegistry = fSchemaGrammar->getGroupInfoRegistry();
- fAttGroupRegistry = fSchemaGrammar->getAttGroupInfoRegistry();
- fAttributeDeclRegistry = fSchemaGrammar->getAttributeDeclRegistry();
- fComplexTypeRegistry = fSchemaGrammar->getComplexTypeRegistry();
- fValidSubstitutionGroups = fSchemaGrammar->getValidSubstitutionGroups();
- fNamespaceScope = fSchemaGrammar->getNamespaceScope();
- fAttributeCheck.setIDRefList(fSchemaGrammar->getIDRefList());
- }
- fSchemaInfo = toRestore;
- fElemAttrDefaultQualified = fSchemaInfo->getElemAttrDefaultQualified();
- fBlockDefault = fSchemaInfo->getBlockDefault();
- fFinalDefault = fSchemaInfo->getFinalDefault();
- }
- bool
- TraverseSchema::emptiableParticle(const ContentSpecNode* const specNode) {
- if (!fFullConstraintChecking ||
- (getMinTotalRange(specNode) == 0)) {
- return true;
- }
- return false;
- }
- int TraverseSchema::getMinTotalRange(const ContentSpecNode* const specNode) {
- if (!specNode) {
- return 0;
- }
- ContentSpecNode::NodeTypes nodeType = specNode->getType();
- const ContentSpecNode* first = 0;
- const ContentSpecNode* second = 0;
- int min = specNode->getMinOccurs();
- if (nodeType == ContentSpecNode::Sequence
- || nodeType == ContentSpecNode::All
- || nodeType == ContentSpecNode::Choice) {
- first = specNode->getFirst();
- second = specNode->getSecond();
- int minFirst = getMinTotalRange(first);
- if (second) {
- int minSecond = getMinTotalRange(second);
- if (nodeType == ContentSpecNode::Choice) {
- min = min * ((minFirst < minSecond)? minFirst : minSecond);
- }
- else {
- min = min * (minFirst + minSecond);
- }
- }
- else
- min = min * minFirst;
- }
- return min;
- }
- int TraverseSchema::getMaxTotalRange(const ContentSpecNode* const specNode) {
- if (!specNode) {
- return 0;
- }
- ContentSpecNode::NodeTypes nodeType = specNode->getType();
- const ContentSpecNode* first = 0;
- const ContentSpecNode* second = 0;
- int max = specNode->getMaxOccurs();
- if (max == SchemaSymbols::UNBOUNDED) {
- return SchemaSymbols::UNBOUNDED;
- }
- if (nodeType == ContentSpecNode::Sequence
- || nodeType == ContentSpecNode::All
- || nodeType == ContentSpecNode::Choice) {
- first = specNode->getFirst();
- second = specNode->getSecond();
- int maxFirst = getMaxTotalRange(first);
- if (maxFirst == SchemaSymbols::UNBOUNDED) {
- return SchemaSymbols::UNBOUNDED;
- }
- if (second) {
- int maxSecond = getMaxTotalRange(second);
- if (maxSecond == SchemaSymbols::UNBOUNDED) {
- return SchemaSymbols::UNBOUNDED;
- }
- else {
- if (nodeType == ContentSpecNode::Choice) {
- max = max * (maxFirst > maxSecond) ? maxFirst : maxSecond;
- }
- else {
- max = max * (maxFirst + maxSecond);
- }
- }
- }
- else {
- max = max * maxFirst;
- }
- }
- return max;
- }
- void TraverseSchema::checkFixedFacet(const DOM_Element& elem,
- const XMLCh* const facetName,
- const DatatypeValidator* const baseDV,
- unsigned int& flags)
- {
- const XMLCh* fixedFacet = getElementAttValue(elem, SchemaSymbols::fgATT_FIXED);
- if (XMLString::stringLen(fixedFacet) &&
- (!XMLString::compareString(fixedFacet, SchemaSymbols::fgATTVAL_TRUE)
- || !XMLString::compareString(fixedFacet, fgValueOne))) {
- if (!XMLString::compareString(SchemaSymbols::fgELT_MINLENGTH, facetName)) {
- flags |= DatatypeValidator::FACET_MINLENGTH;
- }
- else if (!XMLString::compareString(SchemaSymbols::fgELT_MAXLENGTH, facetName)) {
- flags |= DatatypeValidator::FACET_MAXLENGTH;
- }
- else if (!XMLString::compareString(SchemaSymbols::fgELT_MAXEXCLUSIVE, facetName)) {
- flags |= DatatypeValidator::FACET_MAXEXCLUSIVE;
- }
- else if (!XMLString::compareString(SchemaSymbols::fgELT_MAXINCLUSIVE, facetName)) {
- flags |= DatatypeValidator::FACET_MAXINCLUSIVE;
- }
- else if (!XMLString::compareString(SchemaSymbols::fgELT_MINEXCLUSIVE, facetName)) {
- flags |= DatatypeValidator::FACET_MINEXCLUSIVE;
- }
- else if (!XMLString::compareString(SchemaSymbols::fgELT_MININCLUSIVE, facetName)) {
- flags |= DatatypeValidator::FACET_MININCLUSIVE;
- }
- else if (!XMLString::compareString(SchemaSymbols::fgELT_TOTALDIGITS, facetName)) {
- flags |= DatatypeValidator::FACET_TOTALDIGITS;
- }
- else if (!XMLString::compareString(SchemaSymbols::fgELT_FRACTIONDIGITS, facetName)) {
- flags |= DatatypeValidator::FACET_FRACTIONDIGITS;
- }
- else if ((!XMLString::compareString(SchemaSymbols::fgELT_WHITESPACE, facetName)) &&
- baseDV->getType() == DatatypeValidator::String) {
- flags |= DatatypeValidator::FACET_WHITESPACE;
- }
- }
- }
- void TraverseSchema::checkRefElementConsistency() {
- unsigned int refElemSize = fRefElements->size();
- for (unsigned int i=0; i < refElemSize; i++) {
- int elemScope = fRefElemScope->elementAt(i);
- QName* elemQName = fRefElements->elementAt(i);
- unsigned int elemURI = elemQName->getURI();
- const XMLCh* elemName = elemQName->getLocalPart();
- const SchemaElementDecl* elemDecl = (SchemaElementDecl*)
- fSchemaGrammar->getElemDecl(elemURI, elemName, 0, Grammar::TOP_LEVEL_SCOPE);
- if (elemDecl) {
- const SchemaElementDecl* other = (SchemaElementDecl*)
- fSchemaGrammar->getElemDecl(elemURI, elemName, 0, elemScope);
- if (other
- && (elemDecl->getComplexTypeInfo() != other->getComplexTypeInfo() ||
- elemDecl->getDatatypeValidator() != other->getDatatypeValidator())) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateElementDeclaration, elemName);
- continue;
- }
- ValueVectorOf<SchemaElementDecl*>* subsElements = fValidSubstitutionGroups->get(elemName, elemURI);
- if (subsElements) {
- unsigned subsElemSize = subsElements->size();
- for (unsigned int j=0; j < subsElemSize; j++) {
- SchemaElementDecl* subsElem = subsElements->elementAt(j);
- const XMLCh* subsElemName = subsElem->getBaseName();
- SchemaElementDecl* sameScopeElem = (SchemaElementDecl*)
- fSchemaGrammar->getElemDecl(subsElem->getURI(), subsElemName, 0, elemScope);
- if (sameScopeElem
- && (subsElem->getComplexTypeInfo() != sameScopeElem->getComplexTypeInfo()
- || subsElem->getDatatypeValidator() != sameScopeElem->getDatatypeValidator())) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateElementDeclaration, subsElemName);
- }
- }
- }
- }
- }
- }
- void
- TraverseSchema::buildValidSubstitutionListB(SchemaElementDecl* const elemDecl,
- SchemaElementDecl* const subsElemDecl) {
- SchemaElementDecl* tmpElemDecl = subsElemDecl;
- while (true) {
- int elemURI = tmpElemDecl->getURI();
- XMLCh* elemName = tmpElemDecl->getBaseName();
- SchemaElementDecl* chainElem = fSubstitutionGroups->get(elemName, elemURI);
- if (!chainElem || (chainElem == elemDecl)) {
- break;
- }
- int chainElemURI = chainElem->getURI();
- XMLCh* chainElemName = chainElem->getBaseName();
- ValueVectorOf<SchemaElementDecl*>* validSubsElements =
- fValidSubstitutionGroups->get(chainElemName, chainElemURI);
- if (!validSubsElements) {
- if (fTargetNSURI == chainElemURI) {
- break; // an error must have occured
- }
- SchemaGrammar* aGrammar = (SchemaGrammar*)
- fGrammarResolver->getGrammar(fURIStringPool->getValueForId(chainElemURI));
- if (!aGrammar)
- break;
- validSubsElements = aGrammar->getValidSubstitutionGroups()->get(chainElemName, chainElemURI);
- if (!validSubsElements) {
- break;
- }
- validSubsElements = new ValueVectorOf<SchemaElementDecl*>(*validSubsElements);
- fValidSubstitutionGroups->put((void*) chainElemName, chainElemURI, validSubsElements);
- }
- if (validSubsElements->containsElement(elemDecl) ||
- !isSubstitutionGroupValid(chainElem, elemDecl->getComplexTypeInfo(),
- elemDecl->getDatatypeValidator(), 0, false)) {
- break;
- }
- validSubsElements->addElement(elemDecl);
- // update related subs. info in case of circular import
- RefVectorEnumerator<SchemaInfo> importingEnum = fSchemaInfo->getImportingListEnumerator();
- while (importingEnum.hasMoreElements()) {
- const SchemaInfo& curRef = importingEnum.nextElement();
- SchemaGrammar* aGrammar = (SchemaGrammar*) fGrammarResolver->getGrammar(curRef.getTargetNSURIString());
- ValueVectorOf<SchemaElementDecl*>* subsElemList =
- aGrammar->getValidSubstitutionGroups()->get(chainElemName, chainElemURI);
- if (subsElemList && !subsElemList->containsElement(elemDecl)) {
- subsElemList->addElement(elemDecl);
- }
- }
- }
- }
- void
- TraverseSchema::buildValidSubstitutionListF(SchemaElementDecl* const elemDecl,
- SchemaElementDecl* const subsElemDecl) {
- int elemURI = elemDecl->getURI();
- XMLCh* elemName = elemDecl->getBaseName();
- ValueVectorOf<SchemaElementDecl*>* validSubsElements =fValidSubstitutionGroups->get(elemName, elemURI);
- if (validSubsElements) {
- int subsElemURI = subsElemDecl->getURI();
- XMLCh* subsElemName = subsElemDecl->getBaseName();
- ValueVectorOf<SchemaElementDecl*>* validSubs = fValidSubstitutionGroups->get(subsElemName, subsElemURI);
- if (!validSubs) {
- if (fTargetNSURI == subsElemURI) {
- return; // an error must have occured
- }
- SchemaGrammar* aGrammar = (SchemaGrammar*)
- fGrammarResolver->getGrammar(fURIStringPool->getValueForId(subsElemURI));
- if (!aGrammar)
- return;
- validSubs = aGrammar->getValidSubstitutionGroups()->get(subsElemName, subsElemURI);
- if (!validSubs) {
- return;
- }
- validSubs = new ValueVectorOf<SchemaElementDecl*>(*validSubs);
- fValidSubstitutionGroups->put((void*) subsElemName, subsElemURI, validSubs);
- }
- unsigned int elemSize = validSubsElements->size();
- for (unsigned int i=0; i<elemSize; i++) {
- SchemaElementDecl* chainElem = validSubsElements->elementAt(i);
- if (chainElem == subsElemDecl ||
- validSubs->containsElement(chainElem)) {
- continue;
- }
- if (isSubstitutionGroupValid(subsElemDecl, chainElem->getComplexTypeInfo(),
- chainElem->getDatatypeValidator(), 0, false)) {
- validSubs->addElement(chainElem);
- buildValidSubstitutionListB(chainElem, subsElemDecl);
- }
- }
- }
- }
- void TraverseSchema::checkEnumerationRequiredNotation(const XMLCh* const name,
- const XMLCh* const type) {
- const XMLCh* localPart = getLocalPart(type);
- if (!XMLString::compareString(localPart, SchemaSymbols::fgELT_NOTATION)) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::NoNotationType, name);
- }
- }
- XercesGroupInfo* TraverseSchema::processGroupRef(const DOM_Element& elem,
- const XMLCh* const refName) {
- if (XUtil::getFirstChildElement(elem) != 0) {
- reportSchemaError(XMLUni::fgValidityDomain, XMLValid::NoContentForRef, SchemaSymbols::fgELT_GROUP);
- }
- const XMLCh* prefix = getPrefix(refName);
- const XMLCh* localPart = getLocalPart(refName);
- const XMLCh* uriStr = resolvePrefixToURI(prefix);
- fBuffer.set(uriStr);
- fBuffer.append(chComma);
- fBuffer.append(localPart);
- unsigned int nameIndex = fStringPool->addOrFind(fBuffer.getRawBuffer());
- if (fCurrentGroupStack->containsElement(nameIndex)) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::NoCircularDefinition, localPart);
- return 0;
- }
- XercesGroupInfo* groupInfo = 0;
- SchemaInfo* saveInfo = fSchemaInfo;
- SchemaInfo::ListType infoType = SchemaInfo::INCLUDE;
- //if from another schema
- if (XMLString::compareString(uriStr, fTargetNSURIString) != 0) {
- Grammar* aGrammar = fGrammarResolver->getGrammar(uriStr);
- if (!aGrammar || aGrammar->getGrammarType() != Grammar::SchemaGrammarType) {
- reportSchemaError(XMLUni::fgValidityDomain, XMLValid::GrammarNotFound, uriStr);
- return 0;
- }
- groupInfo = ((SchemaGrammar*)aGrammar)->getGroupInfoRegistry()->get(fStringPool->getValueForId(nameIndex));
- if (!groupInfo) {
- SchemaInfo* impInfo = fSchemaInfo->getImportInfo(fURIStringPool->addOrFind(uriStr));
- if (!impInfo) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DeclarationNotFound,
- SchemaSymbols::fgELT_GROUP, uriStr, localPart);
- return 0;
- }
- infoType = SchemaInfo::IMPORT;
- fSchemaInfo->setCurrentScope(fCurrentScope);
- fSchemaInfo->setScopeCount(fScopeCount);
- restoreSchemaInfo(impInfo, infoType);
- }
- }
- else {
- groupInfo = fGroupRegistry->get(fStringPool->getValueForId(nameIndex));
- }
- if (!groupInfo) {
- DOM_Element groupElem = fSchemaInfo->getTopLevelComponent(SchemaSymbols::fgELT_GROUP, localPart, &fSchemaInfo);
- if (groupElem != 0) {
- groupInfo = traverseGroupDecl(groupElem);
- if (groupInfo && fCurrentGroupInfo
- && groupInfo->getScope() == fCurrentGroupInfo->getScope()) {
- copyGroupElements(groupInfo, fCurrentGroupInfo, 0);
- }
- // restore schema information, if necessary
- if (saveInfo != fSchemaInfo) {
- restoreSchemaInfo(saveInfo, infoType);
- }
- return groupInfo;
- }
- else {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DeclarationNotFound,
- SchemaSymbols::fgELT_GROUP, uriStr, localPart);
- }
- }
- if (groupInfo) {
- copyGroupElements(groupInfo, fCurrentGroupInfo, fCurrentComplexType);
- }
- // restore schema information, if necessary
- if (saveInfo != fSchemaInfo) {
- restoreSchemaInfo(saveInfo, infoType);
- }
- return groupInfo;
- }
- XercesAttGroupInfo*
- TraverseSchema::processAttributeGroupRef(const DOM_Element& elem,
- const XMLCh* const refName,
- ComplexTypeInfo* const typeInfo) {
- if (XUtil::getFirstChildElement(elem) != 0) {
- reportSchemaError(XMLUni::fgValidityDomain, XMLValid::NoContentForRef, SchemaSymbols::fgELT_ATTRIBUTEGROUP);
- }
- const XMLCh* prefix = getPrefix(refName);
- const XMLCh* localPart = getLocalPart(refName);
- const XMLCh* uriStr = resolvePrefixToURI(prefix);
- XercesAttGroupInfo* attGroupInfo = 0;
- SchemaInfo* saveInfo = fSchemaInfo;
- SchemaInfo::ListType infoType = SchemaInfo::INCLUDE;
- if (XMLString::compareString(uriStr, fTargetNSURIString) != 0) {
- attGroupInfo = traverseAttributeGroupDeclNS(uriStr, localPart);
- if (!attGroupInfo) {
- SchemaInfo* impInfo = fSchemaInfo->getImportInfo(fURIStringPool->addOrFind(uriStr));
- if (!impInfo) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DeclarationNotFound,
- SchemaSymbols::fgELT_ATTRIBUTEGROUP, uriStr, localPart);
- return 0;
- }
- infoType = SchemaInfo::IMPORT;
- fSchemaInfo->setCurrentScope(fCurrentScope);
- fSchemaInfo->setScopeCount(fScopeCount);
- restoreSchemaInfo(impInfo, infoType);
- }
- }
- else {
- // circular check
- DOM_Node parentElem = elem.getParentNode();
- if (parentElem.getLocalName().equals(SchemaSymbols::fgELT_ATTRIBUTEGROUP)
- && ((DOM_Element&) parentElem).getAttribute(SchemaSymbols::fgATT_NAME).equals(localPart)
- && !(parentElem.getParentNode().getLocalName().equals(SchemaSymbols::fgELT_REDEFINE))) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::NoCircularAttGroup);
- return 0;
- }
- attGroupInfo = fAttGroupRegistry->get(localPart);
- }
- if (!attGroupInfo) {
- // traverse top level attributeGroup - if found
- DOM_Element attGroupElem = fSchemaInfo->getTopLevelComponent(SchemaSymbols::fgELT_ATTRIBUTEGROUP, localPart, &fSchemaInfo);
- if (attGroupElem != 0) {
- attGroupInfo = traverseAttributeGroupDecl(attGroupElem, typeInfo);
- if (attGroupInfo && fCurrentAttGroupInfo) {
- copyAttGroupAttributes(attGroupInfo, fCurrentAttGroupInfo, 0);
- }
- // restore schema information, if necessary
- if (saveInfo != fSchemaInfo) {
- restoreSchemaInfo(saveInfo, infoType);
- }
- return attGroupInfo;
- }
- else {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DeclarationNotFound,
- SchemaSymbols::fgELT_ATTRIBUTEGROUP, uriStr, localPart);
- }
- }
- if (attGroupInfo) {
- copyAttGroupAttributes(attGroupInfo, fCurrentAttGroupInfo, typeInfo);
- }
- // restore schema information, if necessary
- if (saveInfo != fSchemaInfo) {
- restoreSchemaInfo(saveInfo, infoType);
- }
- return attGroupInfo;
- }
- bool TraverseSchema::hasAllContent(const ContentSpecNode* const specNode) {
- if (specNode) {
- const ContentSpecNode* tmpSpecNode = specNode;
- if (specNode->getType() == ContentSpecNode::ZeroOrOne) {
- tmpSpecNode = specNode->getFirst();
- }
- return (tmpSpecNode->getType() == ContentSpecNode::All);
- }
- return false;
- }
- void TraverseSchema::processElements(ComplexTypeInfo* const baseTypeInfo,
- ComplexTypeInfo* const newTypeInfo) {
- unsigned int elemCount = baseTypeInfo->elementCount();
- if (elemCount) {
- int newTypeScope = newTypeInfo->getScopeDefined();
- int schemaURI = fURIStringPool->addOrFind(SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
- for (unsigned int i=0; i < elemCount; i++) {
- SchemaGrammar* aGrammar = fSchemaGrammar;
- SchemaElementDecl* elemDecl = baseTypeInfo->elementAt(i);
- if (!elemDecl) {
- continue;
- }
- int elemURI = elemDecl->getURI();
- if (elemURI != fTargetNSURI && elemURI != schemaURI && elemURI != fEmptyNamespaceURI) {
- Grammar* aGrammar =
- fGrammarResolver->getGrammar(fURIStringPool->getValueForId(elemURI));
- if (!aGrammar || aGrammar->getGrammarType() != Grammar::SchemaGrammarType) {
- continue; // REVISIT - error message
- }
- }
- const XMLCh* localPart = elemDecl->getBaseName();
- const SchemaElementDecl* other = (SchemaElementDecl*)
- aGrammar->getElemDecl(elemURI, localPart, 0, newTypeScope);
- if (other) {
- if (elemDecl->getComplexTypeInfo() != other->getComplexTypeInfo()
- || elemDecl->getDatatypeValidator() != other->getDatatypeValidator()) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateElementDeclaration, localPart);
- }
- }
- else {
- int elemScope = elemDecl->getEnclosingScope();
- newTypeInfo->addElement(elemDecl);
- elemDecl->setEnclosingScope(newTypeScope);
- ((SchemaGrammar*) aGrammar)->putGroupElemDecl(elemDecl);
- elemDecl->setEnclosingScope(elemScope);
- }
- }
- }
- }
- void TraverseSchema::copyGroupElements(XercesGroupInfo* const fromGroup,
- XercesGroupInfo* const toGroup,
- ComplexTypeInfo* const typeInfo) {
- unsigned int elemCount = fromGroup->elementCount();
- int newScope = (typeInfo) ? typeInfo->getScopeDefined() : 0;
- for (unsigned int i = 0; i < elemCount; i++) {
- SchemaElementDecl* elemDecl = fromGroup->elementAt(i);
- if (typeInfo) {
- int elemURI = elemDecl->getURI();
- const XMLCh* localPart = elemDecl->getBaseName();
- const SchemaElementDecl* other = (SchemaElementDecl*)
- fSchemaGrammar->getElemDecl(elemURI, localPart, 0, fCurrentScope);
- if (other) {
- if (elemDecl->getComplexTypeInfo() != other->getComplexTypeInfo()
- || elemDecl->getDatatypeValidator() != other->getDatatypeValidator()) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateElementDeclaration, localPart);
- }
- continue;
- }
- int elemScope = elemDecl->getEnclosingScope();
- elemDecl->setEnclosingScope(newScope);
- typeInfo->addElement(elemDecl);
- fSchemaGrammar->putGroupElemDecl(elemDecl);
- elemDecl->setEnclosingScope(elemScope);
- if (toGroup) {
- toGroup->addElement(elemDecl);
- }
- }
- else {
- if (!toGroup->containsElement(elemDecl)) {
- toGroup->addElement(elemDecl);
- }
- }
- }
- }
- void TraverseSchema::copyAttGroupAttributes(XercesAttGroupInfo* const fromAttGroup,
- XercesAttGroupInfo* const toAttGroup,
- ComplexTypeInfo* const typeInfo) {
- unsigned int attCount = fromAttGroup->attributeCount();
- for (unsigned int i=0; i < attCount; i++) {
- SchemaAttDef* attDef = fromAttGroup->attributeAt(i);
- QName* attName = attDef->getAttName();
- const XMLCh* localPart = attName->getLocalPart();
- DatatypeValidator* attDV = attDef->getDatatypeValidator();
- if (typeInfo) {
- if (typeInfo->getAttDef(localPart, attName->getURI())) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateAttribute, localPart);
- continue;
- }
- if (attDV && attDV->getType() == DatatypeValidator::ID) {
- if (typeInfo->containsAttWithTypeId()) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::AttDeclPropCorrect5, localPart);
- continue;
- }
- typeInfo->setAttWithTypeId(true);
- }
- typeInfo->addAttDef(new SchemaAttDef(attDef));
- if (toAttGroup) {
- toAttGroup->addAttDef(attDef, true);
- }
- }
- else {
- if (toAttGroup->containsAttribute(localPart, attName->getURI())) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateAttribute, localPart);
- continue;
- }
- if (attDV && attDV->getType() == DatatypeValidator::ID) {
- if (toAttGroup->containsTypeWithId()) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::AttGrpPropCorrect3, localPart);
- continue;
- }
- toAttGroup->setTypeWithId(true);
- }
- toAttGroup->addAttDef(attDef, true);
- }
- }
- if (toAttGroup) {
- unsigned int anyAttCount = fromAttGroup->anyAttributeCount();
- for (unsigned int j=0; j < anyAttCount; j++) {
- toAttGroup->addAnyAttDef(fromAttGroup->anyAttributeAt(j), true);
- }
- }
- }
- void
- TraverseSchema::attWildCardIntersection(SchemaAttDef* const resultWildCard,
- const SchemaAttDef* const compareWildCard) {
- XMLAttDef::AttTypes typeR = resultWildCard->getType();
- XMLAttDef::AttTypes typeC = compareWildCard->getType();
- //If either O1 or O2 is any, then the other must be the value.
- if (typeC == XMLAttDef::Any_Any ||
- typeR == XMLAttDef::AttTypes_Unknown) {
- return;
- }
- if (typeR == XMLAttDef::Any_Any ||
- typeC == XMLAttDef::AttTypes_Unknown) {
- resultWildCard->resetNamespaceList();
- copyWildCardData(compareWildCard, resultWildCard);
- return;
- }
- // If either O1 or O2 is a pair of not and a namespace name and the other
- // is a set, then that set, minus the negated namespace name if it was in
- // is the value
- if ((typeC == XMLAttDef::Any_Other && typeR == XMLAttDef::Any_List) ||
- (typeR == XMLAttDef::Any_Other && typeC == XMLAttDef::Any_List)) {
- unsigned int compareURI = 0;
- ValueVectorOf<unsigned int>* nameURIList = 0;
- if (typeC == XMLAttDef::Any_List) {
- nameURIList = compareWildCard->getNamespaceList();
- compareURI = resultWildCard->getAttName()->getURI();
- }
- else {
- nameURIList = resultWildCard->getNamespaceList();
- compareURI = compareWildCard->getAttName()->getURI();
- }
- unsigned int listSize = (nameURIList) ? nameURIList->size() : 0;
- if (listSize) {
- bool found = false;
- ValueVectorOf<unsigned int> tmpURIList(listSize);
- for (unsigned int i=0; i < listSize; i++) {
- unsigned int nameURI = nameURIList->elementAt(i);
- if (nameURI != compareURI) {
- tmpURIList.addElement(nameURI);
- }
- else {
- found = true;
- }
- }
- if (found || typeC == XMLAttDef::Any_List) {
- resultWildCard->setNamespaceList(&tmpURIList);
- }
- }
- if (typeC == XMLAttDef::Any_List) {
- copyWildCardData(compareWildCard, resultWildCard);
- }
- return;
- }
- // If both O1 and O2 are sets, then the intersection of those sets must be
- // the value.
- if (typeR == XMLAttDef::Any_List && typeC == XMLAttDef::Any_List) {
- ValueVectorOf<unsigned int>* uriListR = resultWildCard->getNamespaceList();
- ValueVectorOf<unsigned int>* uriListC = compareWildCard->getNamespaceList();
- unsigned int listSize = (uriListC) ? uriListC->size() : 0;
- if (listSize) {
- ValueVectorOf<unsigned int> tmpURIList(listSize);
- for (unsigned int i=0; i < listSize; i++) {
- unsigned int uriName = uriListC->elementAt(i);
- if (uriListR && uriListR->containsElement(uriName)) {
- tmpURIList.addElement(uriName);
- }
- }
- resultWildCard->setNamespaceList(&tmpURIList);
- }
- else {
- resultWildCard->resetNamespaceList();
- }
- return;
- }
- // If the two are negations of different namespace names, then the
- // intersection is not expressible.
- if (typeR == XMLAttDef::Any_Other && typeC == XMLAttDef::Any_Other) {
- QName* qnameR = resultWildCard->getAttName();
- if (qnameR->getURI() != compareWildCard->getAttName()->getURI()) {
- qnameR->setURI(fEmptyNamespaceURI);
- resultWildCard->setType(XMLAttDef::AttTypes_Unknown);
- }
- }
- }
- void
- TraverseSchema::attWildCardUnion(SchemaAttDef* const resultWildCard,
- const SchemaAttDef* const compareWildCard) {
- XMLAttDef::AttTypes typeR = resultWildCard->getType();
- XMLAttDef::AttTypes typeC = compareWildCard->getType();
- //If either O1 or O2 is any, then the other must be the value.
- if (typeR == XMLAttDef::Any_Any ||
- typeR == XMLAttDef::AttTypes_Unknown) {
- return;
- }
- if (typeC == XMLAttDef::Any_Any ||
- typeC == XMLAttDef::AttTypes_Unknown) {
- resultWildCard->resetNamespaceList();
- copyWildCardData(compareWildCard, resultWildCard);
- return;
- }
- // If both O1 and O2 are sets, then the union of those sets must be
- // the value.
- if (typeR == XMLAttDef::Any_List && typeC == XMLAttDef::Any_List) {
- ValueVectorOf<unsigned int>* uriListR = resultWildCard->getNamespaceList();
- ValueVectorOf<unsigned int>* uriListC = compareWildCard->getNamespaceList();
- unsigned int listSizeC = (uriListC) ? uriListC->size() : 0;
- if (listSizeC) {
- if (!uriListR || !uriListR->size()) {
- resultWildCard->setNamespaceList(uriListC);
- return;
- }
- ValueVectorOf<unsigned int> tmpURIList(*uriListR);
- for (unsigned int i = 0; i < listSizeC; i++) {
- unsigned int uriName = uriListC->elementAt(i);
- if (!uriListR->containsElement(uriName)) {
- tmpURIList.addElement(uriName);
- }
- }
- resultWildCard->setNamespaceList(&tmpURIList);
- }
- return;
- }
- // If the two are negations of different namespace names, then any must
- // be the value
- if (typeR == XMLAttDef::Any_Other && typeC == XMLAttDef::Any_Other) {
- QName* qnameR = resultWildCard->getAttName();
- if (qnameR->getURI() != compareWildCard->getAttName()->getURI()) {
- qnameR->setURI(fEmptyNamespaceURI);
- resultWildCard->setType(XMLAttDef::Any_Any);
- }
- }
- // If either O1 or O2 is a pair of not and a namespace name and the other
- // is a set, then:
- // 1. If the set includes the negated namespace name, then any must be the value.
- // 2. If the set does not include the negated namespace name, then whichever of O1 or O2 is a
- // pair of not and a namespace name must be the value.
- if ((typeC == XMLAttDef::Any_Other && typeR == XMLAttDef::Any_List) ||
- (typeR == XMLAttDef::Any_Other && typeC == XMLAttDef::Any_List)) {
- ValueVectorOf<unsigned int>* nameURIList = 0;
- QName* attNameR = resultWildCard->getAttName();
- unsigned int compareURI = 0;
- if (typeC == XMLAttDef::Any_List) {
- nameURIList = compareWildCard->getNamespaceList();
- compareURI = attNameR->getURI();
- }
- else {
- nameURIList = resultWildCard->getNamespaceList();
- compareURI = compareWildCard->getAttName()->getURI();
- }
- if (nameURIList && nameURIList->containsElement(compareURI)) {
- resultWildCard->setType(XMLAttDef::Any_Any);
- attNameR->setURI(fEmptyNamespaceURI);
- }
- else if (typeR == XMLAttDef::Any_List) {
- resultWildCard->setType(XMLAttDef::Any_Other);
- attNameR->setURI(compareURI);
- }
- resultWildCard->resetNamespaceList();
- }
- }
- void TraverseSchema::checkAttDerivationOK(const ComplexTypeInfo* const baseTypeInfo,
- const ComplexTypeInfo* const childTypeInfo) {
- SchemaAttDefList& childAttList = (SchemaAttDefList&) childTypeInfo->getAttDefList();
- const SchemaAttDef* baseAttWildCard = baseTypeInfo->getAttWildCard();
- while (childAttList.hasMoreElements()) {
- SchemaAttDef& childAttDef = (SchemaAttDef&) childAttList.nextElement();
- QName* childAttName = childAttDef.getAttName();
- const XMLCh* childLocalPart = childAttName->getLocalPart();
- const SchemaAttDef* baseAttDef = baseTypeInfo->getAttDef(childLocalPart, childAttName->getURI());
- if (baseAttDef) {
- XMLAttDef::DefAttTypes baseAttDefType = baseAttDef->getDefaultType();
- XMLAttDef::DefAttTypes childAttDefType = childAttDef.getDefaultType();
- // Constraint 2.1.1 & 3 + check for prohibited base attribute
- if (baseAttDefType == XMLAttDef::Prohibited
- && childAttDefType != XMLAttDef::Prohibited) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_8, childLocalPart);
- }
- if ((baseAttDefType & XMLAttDef::Required)
- && !(childAttDefType & XMLAttDef::Required)) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_2, childLocalPart);
- }
- // Constraint 2.1.2
- DatatypeValidator* baseDV = baseAttDef->getDatatypeValidator();
- DatatypeValidator* childDV = childAttDef.getDatatypeValidator();
- if (!baseDV || !baseDV->isSubstitutableBy(childDV)) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_3, childLocalPart);
- }
- // Constraint 2.1.3
- if ((baseAttDefType & XMLAttDef::Fixed) &&
- (!(childAttDefType & XMLAttDef::Fixed) ||
- XMLString::compareString(baseAttDef->getValue(), childAttDef.getValue()))) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_4, childLocalPart);
- }
- }
- // Constraint 2.2
- else if (!baseAttWildCard ||
- !wildcardAllowsNamespace(baseAttWildCard, childAttName->getURI())) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_5, childLocalPart);
- }
- }
- // Constraint 4
- const SchemaAttDef* childAttWildCard = childTypeInfo->getAttWildCard();
- if (childAttWildCard) {
- if (!baseAttWildCard) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_6);
- }
- else if (!isWildCardSubset(baseAttWildCard, childAttWildCard)) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_7);
- }
- }
- }
- void TraverseSchema::checkAttDerivationOK(const XercesAttGroupInfo* const baseAttGrpInfo,
- const XercesAttGroupInfo* const childAttGrpInfo) {
- unsigned int baseAttCount = baseAttGrpInfo->attributeCount();
- unsigned int baseAnyAttCount = baseAttGrpInfo->anyAttributeCount();
- unsigned int childAttCount = childAttGrpInfo->attributeCount();
- unsigned int childAnyAttCount = childAttGrpInfo->anyAttributeCount();
- if ((childAttCount || childAnyAttCount) && (!baseAttCount && !baseAnyAttCount)) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_1);
- }
- const SchemaAttDef* baseAttWildCard = (baseAnyAttCount) ? baseAttGrpInfo->anyAttributeAt(0) : 0;
- for (unsigned int i=0; i<childAttCount; i++) {
- const SchemaAttDef* childAttDef = childAttGrpInfo->attributeAt(i);
- QName* childAttName = childAttDef->getAttName();
- const XMLCh* childLocalPart = childAttName->getLocalPart();
- const SchemaAttDef* baseAttDef = baseAttGrpInfo->getAttDef(childLocalPart, childAttName->getURI());
- if (baseAttDef) {
- XMLAttDef::DefAttTypes baseAttDefType = baseAttDef->getDefaultType();
- XMLAttDef::DefAttTypes childAttDefType = childAttDef->getDefaultType();
- // Constraint 2.1.1 & 3 + check for prohibited base attribute
- if (baseAttDefType == XMLAttDef::Prohibited
- && childAttDefType != XMLAttDef::Prohibited) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_8, childLocalPart);
- }
- if ((baseAttDefType & XMLAttDef::Required)
- && !(childAttDefType & XMLAttDef::Required)) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_2, childLocalPart);
- }
- // Constraint 2.1.2
- DatatypeValidator* baseDV = baseAttDef->getDatatypeValidator();
- DatatypeValidator* childDV = childAttDef->getDatatypeValidator();
- if (!baseDV || !baseDV->isSubstitutableBy(childDV)) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_3, childLocalPart);
- }
- // Constraint 2.1.3
- if ((baseAttDefType & XMLAttDef::Fixed) &&
- (!(childAttDefType & XMLAttDef::Fixed) ||
- XMLString::compareString(baseAttDef->getValue(), childAttDef->getValue()))) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_4, childLocalPart);
- }
- }
- // Constraint 2.2
- else if (!baseAttWildCard ||
- !wildcardAllowsNamespace(baseAttWildCard, childAttName->getURI())) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_5, childLocalPart);
- }
- }
- // Constraint 4
- const SchemaAttDef* childAttWildCard = (childAnyAttCount) ? childAttGrpInfo->anyAttributeAt(0) : 0;
- if (childAttWildCard) {
- if (!baseAttWildCard) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_6);
- }
- else if (!isWildCardSubset(baseAttWildCard, childAttWildCard)) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_7);
- }
- }
- }
- bool TraverseSchema::wildcardAllowsNamespace(const SchemaAttDef* const wildCard,
- const unsigned int nameURI) {
- XMLAttDef::AttTypes wildCardType = wildCard->getType();
- // The constraint must be any
- if (wildCardType == XMLAttDef::Any_Any) {
- return true;
- }
- // All of the following must be true:
- // 2.1 The constraint is a pair of not and a namespace name or 穉bsent
- // 2.2 The value must not be identical to the 穘amespace test