/*** * Return an XSModel derived from the components of all SchemaGrammars * in the grammar pool. If the pool is locked, this should * be a thread-safe operation. * * NOTE: The function should NEVER return NULL. If there are no grammars in * the pool it should return an XSModel containing the Schema for Schema. * * Calling getXSModel() on an unlocked grammar pool may result in the * creation of a new XSModel with the old XSModel being deleted. * The bool parameter will indicate if the XSModel was changed. * * For source code compatibility, default implementation is to say * XSModelWasChanged. */ virtual XSModel *getXSModel(bool& XSModelWasChanged) { XSModelWasChanged = true; return getXSModel(); }
void startElement( const XMLCh* namespaceURI, const XMLCh* lName, const XMLCh* qName, const xercesc::Attributes& attrs) { std::shared_ptr<Fragment> fragment; if (namespaceURI == XS(XMLConstants::XMLSchemaNamespace)) { if (lName == L"group") { fragment = std::make_shared<SchemaGroupCompositor>(); } else if (lName == L"all") { fragment = std::make_shared<SchemaAllCompositor>(); } else if (lName == L"choice") { fragment = std::make_shared<SchemaChoiceCompositor>(); } else if (lName == L"sequence") { fragment = std::make_shared<SchemaSequenceCompositor>(); } else if (lName == L"complexType") { fragment = std::make_shared<TypeDeclaration>(); } else if (lName == L"simpleType") { fragment = std::make_shared<SimpleTypeDeclaration>(); } else if (lName == L"attribute") { fragment = std::make_shared<AttributeDeclaration>(); } else if (lName == L"attributeGroup") { fragment = std::make_shared<AttributeGroupDeclaration>(); } else if (lName == L"schema") { fragment = std::make_shared<Schema>(); setXSModel(constructXSModel()); setTargetNamespace(std::shared_ptr<const XMLCh>(attrs.getValue(L"targetNamespace"))); } else if (lName == L"element") { auto elementName = std::shared_ptr<const XMLCh>(attrs.getValue(L"name")); if (!getXSModel().get()) { throw new XBRLException("An XML Schema element declaration was found outside of an XML Schema."); } auto targetNamespace = getTargetNamespace(); if (!targetNamespace.get()) { throw new XBRLException("An XML Schema element was found without a target namespace."); } // Find the XS model element declaration for the element that has been started - if one can be found std::shared_ptr<XSElementDeclaration> declaration; // Handle anonymous schemas first - these are the tough case if (targetNamespace.get()) { // Get the list of namespaces declared in the model auto nsItemList = std::shared_ptr<XSNamespaceItemList>(getXSModel()->getNamespaceItems()); // For each namespace ... for (XMLSize_t i=0; i < nsItemList->size(); ++i) { auto nsItem = std::shared_ptr<XSNamespaceItem>(nsItemList->elementAt(i)); // Get a candidate element declaration if one exists auto candidateDeclaration = std::shared_ptr<XSElementDeclaration>(nsItem->getElementDeclaration(elementName.get())); if (candidateDeclaration.get()) { // Get the URIs of the documents that were used to create elements in this namespace auto locations = std::shared_ptr<const StringList>(nsItem->getDocumentLocations()); // Check to see if the current document URI is one of those documents and if so, the candidate could be good for (XMLSize_t j=0; j < locations->size(); ++j) { auto location = locations->elementAt(j); if (to_string(location) == contentHandler->getURI().toString()) { // Throw an exception if we find two feasible candidate element declarations in the Schema model if (declaration.get()) throw new XBRLException("Potentially ambiguous anonymous Schema problem."); declaration = candidateDeclaration; } } } } if (!declaration.get()) throw new XBRLException("An element declaration was found that could not be handled."); // Handle the easy case where the schema specifies its target namespace } else if (elementName.get()) { declaration = std::shared_ptr<XSElementDeclaration>( getXSModel()->getElementDeclaration(elementName.get(), getTargetNamespace().get())); } // Determine what substitution groups the element is in - if any. if (declaration.get()) { auto sgDeclaration = std::shared_ptr<XSElementDeclaration>(declaration->getSubstitutionGroupAffiliation()); while (sgDeclaration.get()) { if (to_string(sgDeclaration->getNamespace()) == XMLConstants::XBRL21Namespace) { if (sgDeclaration->getName() == L"item") { fragment = std::shared_ptr<Concept>(); break; } else if (sgDeclaration->getName() == L"tuple") { fragment = std::shared_ptr<Concept>(); break; } } if (to_string(sgDeclaration->getNamespace()) == XMLConstants::XBRL21LinkNamespace) { //if (sgDeclaration->getName() == L"part") // fragment = std::shared_ptr<ReferencePartDeclaration>(); break; } sgDeclaration = std::shared_ptr<XSElementDeclaration>(sgDeclaration->getSubstitutionGroupAffiliation()); } } if (!fragment.get()) { fragment = std::shared_ptr<ElementDeclaration>(); } } if (fragment.get()) { outer.lock()->processFragment(fragment, attrs); } } }