igxmlscanner2.cpp
来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 1,601 行 · 第 1/5 页
CPP
1,601 行
/* * Copyright 2002, 2003,2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* * $Id: IGXMLScanner2.cpp,v 1.74 2004/09/29 19:23:32 knoaman Exp $ */// ---------------------------------------------------------------------------// This file holds some of the grunt work methods of IGXMLScanner.cpp to keep// it a little more readable.// ---------------------------------------------------------------------------// ---------------------------------------------------------------------------// Includes// ---------------------------------------------------------------------------#include <xercesc/internal/IGXMLScanner.hpp>#include <xercesc/internal/EndOfEntityException.hpp>#include <xercesc/util/UnexpectedEOFException.hpp>#include <xercesc/util/XMLUri.hpp>#include <xercesc/framework/LocalFileInputSource.hpp>#include <xercesc/framework/URLInputSource.hpp>#include <xercesc/framework/XMLDocumentHandler.hpp>#include <xercesc/framework/XMLEntityHandler.hpp>#include <xercesc/framework/XMLPScanToken.hpp>#include <xercesc/framework/XMLRefInfo.hpp>#include <xercesc/framework/XMLGrammarPool.hpp>#include <xercesc/framework/psvi/PSVIAttributeList.hpp>#include <xercesc/framework/psvi/PSVIElement.hpp>#include <xercesc/validators/common/ContentLeafNameTypeVector.hpp>#include <xercesc/validators/DTD/DTDGrammar.hpp>#include <xercesc/validators/DTD/DTDValidator.hpp>#include <xercesc/validators/DTD/XMLDTDDescriptionImpl.hpp>#include <xercesc/validators/datatype/DatatypeValidator.hpp>#include <xercesc/validators/schema/XMLSchemaDescriptionImpl.hpp>#include <xercesc/validators/schema/SchemaGrammar.hpp>#include <xercesc/validators/schema/SchemaValidator.hpp>#include <xercesc/validators/schema/TraverseSchema.hpp>#include <xercesc/validators/schema/SubstitutionGroupComparator.hpp>#include <xercesc/validators/schema/XSDDOMParser.hpp>#include <xercesc/validators/schema/identity/IdentityConstraintHandler.hpp>XERCES_CPP_NAMESPACE_BEGINinline XMLAttDefList& getAttDefList(bool isSchemaGrammar , ComplexTypeInfo* currType , XMLElementDecl* elemDecl);// ---------------------------------------------------------------------------// IGXMLScanner: Private helper methods// ---------------------------------------------------------------------------// This method is called from scanStartTagNS() to build up the list of// XMLAttr objects that will be passed out in the start tag callout. We// get the key/value pairs from the raw scan of explicitly provided attrs,// which have not been normalized. And we get the element declaration from// which we will get any defaulted or fixed attribute defs and add those// in as well.unsigned intIGXMLScanner::buildAttList(const RefVectorOf<KVStringPair>& providedAttrs , const unsigned int attCount , XMLElementDecl* elemDecl , RefVectorOf<XMLAttr>& toFill){ // If doing DTD's, Ask the element to clear the 'provided' flag on all of the att defs // that it owns, and to return us a boolean indicating whether it has // any defs. If schemas are being validated, the complexType // at the top of the SchemaValidator's stack will // know what's best. REVISIT: don't modify grammar at all; eliminate // this step... ComplexTypeInfo *currType = 0; DatatypeValidator *currDV = 0; if(fGrammar->getGrammarType() == Grammar::SchemaGrammarType && fValidate) { currType = ((SchemaValidator*)fValidator)->getCurrentTypeInfo(); if (!currType) { currDV = ((SchemaValidator*)fValidator)->getCurrentDatatypeValidator(); } } const bool hasDefs = (currType && fValidate) ? currType->resetDefs() : elemDecl->resetDefs(); // another set of attributes; increment element counter fElemCount++; // If there are no expliclitily provided attributes and there are no // defined attributes for the element, the we don't have anything to do. // So just return zero in this case. if (!hasDefs && !attCount) return 0; // Keep up with how many attrs we end up with total unsigned int retCount = 0; // And get the current size of the output vector. This lets us use // existing elements until we fill it, then start adding new ones. const unsigned int curAttListSize = toFill.size(); // We need a buffer into which raw scanned attribute values will be // normalized. XMLBufBid bbNormal(&fBufMgr); XMLBuffer& normBuf = bbNormal.getBuffer(); // // Decide if to use hash table to do duplicate checking // bool toUseHashTable = false; if (fGrammarType == Grammar::DTDGrammarType) { setAttrDupChkRegistry(attCount, toUseHashTable); } // Loop through our explicitly provided attributes, which are in the raw // scanned form, and build up XMLAttr objects. unsigned int index; for (index = 0; index < attCount; index++) { PSVIItem::VALIDITY_STATE attrValid = PSVIItem::VALIDITY_VALID; PSVIItem::ASSESSMENT_TYPE attrAssessed = PSVIItem::VALIDATION_FULL; const KVStringPair* curPair = providedAttrs.elementAt(index); // We have to split the name into its prefix and name parts. Then // we map the prefix to its URI. const XMLCh* const namePtr = curPair->getKey(); ArrayJanitor<XMLCh> janName(0); // use a stack-based buffer when possible. XMLCh tempBuffer[100]; const int colonInd = XMLString::indexOf(namePtr, chColon); const XMLCh* prefPtr = XMLUni::fgZeroLenString; const XMLCh* suffPtr = XMLUni::fgZeroLenString; if (colonInd != -1) { // We have to split the string, so make a copy. if (XMLString::stringLen(namePtr) < sizeof(tempBuffer) / sizeof(tempBuffer[0])) { XMLString::copyString(tempBuffer, namePtr); tempBuffer[colonInd] = chNull; prefPtr = tempBuffer; } else { janName.reset(XMLString::replicate(namePtr, fMemoryManager), fMemoryManager); janName[colonInd] = chNull; prefPtr = janName.get(); } suffPtr = namePtr + colonInd + 1; } else { // No colon, so we just have a name with no prefix suffPtr = namePtr; } // Map the prefix to a URI id. We tell him that we are mapping an // attr prefix, so any xmlns attrs at this level will not affect it. const unsigned int uriId = resolvePrefix(prefPtr, ElemStack::Mode_Attribute); // If the uri comes back as the xmlns or xml URI or its just a name // and that name is 'xmlns', then we handle it specially. So set a // boolean flag that lets us quickly below know which we are dealing // with. const bool isNSAttr = (uriId == fXMLNSNamespaceId) || (uriId == fXMLNamespaceId) || XMLString::equals(suffPtr, XMLUni::fgXMLNSString) || XMLString::equals(getURIText(uriId), SchemaSymbols::fgURI_XSI); // If its not a special case namespace attr of some sort, then we // do normal checking and processing. XMLAttDef::AttTypes attType; DatatypeValidator *attrValidator = 0; PSVIAttribute *psviAttr = 0; if (!isNSAttr || fGrammarType == Grammar::DTDGrammarType) { // Some checking for attribute wild card first (for schema) bool laxThisOne = false; bool skipThisOne = false; XMLAttDef* attDefForWildCard = 0; XMLAttDef* attDef = 0; if (fGrammarType == Grammar::SchemaGrammarType) { //retrieve the att def SchemaAttDef* attWildCard = 0; if (currType) { attDef = currType->getAttDef(suffPtr, uriId); attWildCard = currType->getAttWildCard(); } else if (!currDV) { // check explicitly-set wildcard attWildCard = ((SchemaElementDecl*)elemDecl)->getAttWildCard(); } // if not found or faulted in - check for a matching wildcard attribute // if no matching wildcard attribute, check (un)qualifed cases and flag // appropriate errors if (!attDef || (attDef->getCreateReason() == XMLAttDef::JustFaultIn)) { if (attWildCard) { //if schema, see if we should lax or skip the validation of this attribute if (anyAttributeValidation(attWildCard, uriId, skipThisOne, laxThisOne)) { if(!skipThisOne) { SchemaGrammar* sGrammar = (SchemaGrammar*) fGrammarResolver->getGrammar(getURIText(uriId)); if (sGrammar && sGrammar->getGrammarType() == Grammar::SchemaGrammarType) { RefHashTableOf<XMLAttDef>* attRegistry = sGrammar->getAttributeDeclRegistry(); if (attRegistry) { attDefForWildCard = attRegistry->get(suffPtr); } } } } } else if (currType) { // not found, see if the attDef should be qualified or not if (uriId == fEmptyNamespaceId) { attDef = currType->getAttDef(suffPtr , fURIStringPool->getId(fGrammar->getTargetNamespace())); if (fValidate && attDef && attDef->getCreateReason() != XMLAttDef::JustFaultIn) { // the attribute should be qualified fValidator->emitError ( XMLValid::AttributeNotQualified , attDef->getFullName() ); if(fGrammarType == Grammar::SchemaGrammarType) { fPSVIElemContext.fErrorOccurred = true; if (getPSVIHandler()) { attrValid = PSVIItem::VALIDITY_INVALID; } } } } else { attDef = currType->getAttDef(suffPtr , fEmptyNamespaceId); if (fValidate && attDef && attDef->getCreateReason() != XMLAttDef::JustFaultIn) { // the attribute should be qualified fValidator->emitError ( XMLValid::AttributeNotUnQualified , attDef->getFullName() ); if(fGrammarType == Grammar::SchemaGrammarType) { fPSVIElemContext.fErrorOccurred = true; if (getPSVIHandler()) { attrValid = PSVIItem::VALIDITY_INVALID; } } } } } } } // Find this attribute within the parent element. We pass both // the uriID/name and the raw QName buffer, since we don't know // how the derived validator and its elements store attributes. else { if(fGrammarType == Grammar::DTDGrammarType) attDef = ((DTDElementDecl *)elemDecl)->getAttDef ( namePtr); } // now need to prepare for duplicate detection if(attDef) { unsigned int *curCountPtr = fAttDefRegistry->get(attDef); if(!curCountPtr) { curCountPtr = getNewUIntPtr(); *curCountPtr = fElemCount; fAttDefRegistry->put(attDef, curCountPtr); } else if(*curCountPtr < fElemCount) *curCountPtr = fElemCount; else { emitError ( XMLErrs::AttrAlreadyUsedInSTag , attDef->getFullName() , elemDecl->getFullName() ); fPSVIElemContext.fErrorOccurred = true; } } else { if(fGrammarType == Grammar::DTDGrammarType) { unsigned int *curCountPtr = fUndeclaredAttrRegistry->get(namePtr); if(!curCountPtr) { curCountPtr = getNewUIntPtr();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?