Example #1
0
 /***
   * 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();
 }
Example #2
0
		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);
				}
			}
		}