sgxmlscanner.cpp
来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 1,881 行 · 第 1/5 页
CPP
1,881 行
} } // Validate the element if (fValidate) { fValidator->validateElement(elemDecl); if (((SchemaValidator*) fValidator)->getErrorOccurred()) fPSVIElemContext.fErrorOccurred = true; } // squirrel away the element's QName, so that we can do an efficient // end-tag match fElemStack.setCurrentSchemaElemName(fQNameBuf.getRawBuffer()); ComplexTypeInfo* typeinfo = (fValidate) ? ((SchemaValidator*)fValidator)->getCurrentTypeInfo() : ((SchemaElementDecl*) elemDecl)->getComplexTypeInfo(); if (typeinfo) { currentScope = typeinfo->getScopeDefined(); // switch grammar if the typeinfo has a different grammar (happens when there is xsi:type) XMLCh* typeName = typeinfo->getTypeName(); const XMLCh poundStr[] = {chPound, chNull}; if (!XMLString::startsWith(typeName, poundStr)) { const int comma = XMLString::indexOf(typeName, chComma); if (comma > 0) { XMLBuffer prefixBuf(comma+1, fMemoryManager); prefixBuf.append(typeName, comma); const XMLCh* uriStr = prefixBuf.getRawBuffer(); bool errorCondition = !switchGrammar(uriStr) && fValidate; if (errorCondition && !laxThisOne) { fValidator->emitError ( XMLValid::GrammarNotFound , prefixBuf.getRawBuffer() ); } } } } fElemStack.setCurrentScope(currentScope); // Set element next state if (elemDepth >= fElemStateSize) { resizeElemState(); } fElemState[elemDepth] = 0; fElemStack.setCurrentGrammar(fGrammar); // If this is the first element and we are validating, check the root // element. if (isRoot) { if (fValidate) { // Some validators may also want to check the root, call the // XMLValidator::checkRootElement if (fValidatorFromUser && !fValidator->checkRootElement(elemDecl->getId())) { fValidator->emitError(XMLValid::RootElemNotLikeDocType); } } } else if (parentValidation) { // If the element stack is not empty, then add this element as a // child of the previous top element. If its empty, this is the root // elem and is not the child of anything. fElemStack.addChild(elemDecl->getElementName(), true); } // PSVI handling: must reset this, even if no attributes... if(getPSVIHandler()) fPSVIAttrList->reset(); // Now lets get the fAttrList filled in. This involves faulting in any // defaulted and fixed attributes and normalizing the values of any that // we got explicitly. // // We update the attCount value with the total number of attributes, but // it goes in with the number of values we got during the raw scan of // explictly provided attrs above. attCount = buildAttList(*fRawAttrList, attCount, elemDecl, *fAttrList); if(attCount) { // clean up after ourselves: // clear the map used to detect duplicate attributes fUndeclaredAttrRegistryNS->removeAll(); } // activate identity constraints if (toCheckIdentityConstraint()) { fICHandler->activateIdentityConstraint ( (SchemaElementDecl*) elemDecl , (int) elemDepth , uriId , fPrefixBuf.getRawBuffer() , *fAttrList , attCount ); } // Since the element may have default values, call start tag now regardless if it is empty or not // If we have a document handler, then tell it about this start tag if (fDocHandler) { fDocHandler->startElement ( *elemDecl , uriId , fPrefixBuf.getRawBuffer() , *fAttrList , attCount , false , isRoot ); } // may be where we output something... // if we have a PSVIHandler, now's the time to call // its handleAttributesPSVI method: if(fPSVIHandler) { QName *eName = elemDecl->getElementName(); fPSVIHandler->handleAttributesPSVI ( eName->getLocalPart() , fURIStringPool->getValueForId(eName->getURI()) , fPSVIAttrList ); } // If empty, validate content right now if we are validating and then // pop the element stack top. Else, we have to update the current stack // top's namespace mapping elements. if (isEmpty) { // Pop the element stack back off since it'll never be used now fElemStack.popTop(); // reset current type info DatatypeValidator* psviMemberType = 0; if (fGrammarType == Grammar::SchemaGrammarType) { if (fValidate && elemDecl->isDeclared()) { fPSVIElemContext.fCurrentTypeInfo = ((SchemaValidator*) fValidator)->getCurrentTypeInfo(); if(!fPSVIElemContext.fCurrentTypeInfo) fPSVIElemContext.fCurrentDV = ((SchemaValidator*) fValidator)->getCurrentDatatypeValidator(); else fPSVIElemContext.fCurrentDV = 0; if(fPSVIHandler) { fPSVIElemContext.fNormalizedValue = ((SchemaValidator*) fValidator)->getNormalizedValue(); if (XMLString::equals(fPSVIElemContext.fNormalizedValue, XMLUni::fgZeroLenString)) fPSVIElemContext.fNormalizedValue = 0; } } else { fPSVIElemContext.fCurrentDV = 0; fPSVIElemContext.fCurrentTypeInfo = 0; fPSVIElemContext.fNormalizedValue = 0; } } // If validating, then insure that its legal to have no content if (fValidate) { const int res = fValidator->checkContent(elemDecl, 0, 0); if (res >= 0) { // REVISIT: in the case of xsi:type, this may // return the wrong string... fValidator->emitError ( XMLValid::ElementNotValidForContent , elemDecl->getFullName() , elemDecl->getFormattedContentModel() ); } if (((SchemaValidator*) fValidator)->getErrorOccurred()) fPSVIElemContext.fErrorOccurred = true; // note that if we're empty, won't be a current DV else { if (fPSVIHandler) { fPSVIElemContext.fIsSpecified = ((SchemaValidator*) fValidator)->getIsElemSpecified(); if(fPSVIElemContext.fIsSpecified) fPSVIElemContext.fNormalizedValue = ((SchemaElementDecl *)elemDecl)->getDefaultValue(); } if (fPSVIElemContext.fCurrentDV && fPSVIElemContext.fCurrentDV->getType() == DatatypeValidator::Union) psviMemberType = fValidationContext->getValidatingMemberType(); } // call matchers and de-activate context if (toCheckIdentityConstraint()) { fICHandler->deactivateContext ( (SchemaElementDecl *) elemDecl , fContent.getRawBuffer() ); } } if (fPSVIHandler) { endElementPSVI ( (SchemaElementDecl*)elemDecl, psviMemberType ); } // If we have a doc handler, tell it about the end tag if (fDocHandler) { fDocHandler->endElement ( *elemDecl , uriId , isRoot , fPrefixBuf.getRawBuffer() ); } // If the elem stack is empty, then it was an empty root if (isRoot) gotData = false; else { // Restore the grammar fGrammar = fElemStack.getCurrentGrammar(); fGrammarType = fGrammar->getGrammarType(); fValidator->setGrammar(fGrammar); // Restore the validation flag fValidate = fElemStack.getValidationFlag(); } } else // not empty { // send a partial element psvi if (fPSVIHandler) { ComplexTypeInfo* curTypeInfo = 0; DatatypeValidator* curDV = 0; XSTypeDefinition* typeDef = 0; if (fValidate && elemDecl->isDeclared()) { curTypeInfo = ((SchemaValidator*) fValidator)->getCurrentTypeInfo(); if (curTypeInfo) { typeDef = (XSTypeDefinition*) fModel->getXSObject(curTypeInfo); } else { curDV = ((SchemaValidator*) fValidator)->getCurrentDatatypeValidator(); if (curDV) { typeDef = (XSTypeDefinition*) fModel->getXSObject(curDV); } } } fPSVIElement->reset ( PSVIElement::VALIDITY_NOTKNOWN , PSVIElement::VALIDATION_NONE , fRootElemName , ((SchemaValidator*) fValidator)->getIsElemSpecified() , (elemDecl->isDeclared()) ? (XSElementDeclaration*) fModel->getXSObject(elemDecl) : 0 , typeDef , 0 //memberType , fModel , ((SchemaElementDecl*)elemDecl)->getDefaultValue() , 0 , 0 , 0 ); fPSVIHandler->handlePartialElementPSVI ( elemDecl->getBaseName() , fURIStringPool->getValueForId(elemDecl->getURI()) , fPSVIElement ); } fErrorStack->push(fPSVIElemContext.fErrorOccurred); } return true;}unsigned intSGXMLScanner::resolveQName(const XMLCh* const qName , XMLBuffer& prefixBuf , const short mode , int& prefixColonPos){ // Lets split out the qName into a URI and name buffer first. The URI // can be empty. prefixColonPos = XMLString::indexOf(qName, chColon); if (prefixColonPos == -1) { // Its all name with no prefix, so put the whole thing into the name // buffer. Then map the empty string to a URI, since the empty string // represents the default namespace. This will either return some // explicit URI which the default namespace is mapped to, or the // the default global namespace. bool unknown = false; prefixBuf.reset(); return fElemStack.mapPrefixToURI(XMLUni::fgZeroLenString, (ElemStack::MapModes) mode, unknown); } else { // Copy the chars up to but not including the colon into the prefix // buffer. prefixBuf.set(qName, prefixColonPos); // Watch for the special namespace prefixes. We always map these to // special URIs. 'xml' gets mapped to the official URI that its defined // to map to by the NS spec. xmlns gets mapped to a special place holder // URI that we define (so that it maps to something checkable.) const XMLCh* prefixRawBuf = prefixBuf.getRawBuffer(); if (XMLString::equals(prefixRawBuf, XMLUni::fgXMLNSString)) { // if this is an element, it is an error to have xmlns as prefix if (mode == ElemStack::Mode_Element) emitError(XMLErrs::NoXMLNSAsElementPrefix, qName); return fXMLNSNamespaceId; } else if (XMLString::equals(prefixRawBuf, XMLUni::fgXMLString)) { return fXMLNamespaceId; } else { bool unknown = false; unsigned int uriId = fElemStack.mapPrefixToURI(prefixRawBuf, (ElemStack::MapModes) mode, unknown); if (unknown) emitError(XMLErrs::UnknownPrefix, prefixRawBuf); return uriId; } }}// ---------------------------------------------------------------------------// SGXMLScanner: Grammar preparsing// -------------
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?