GME
13
|
00001 /* 00002 * Licensed to the Apache Software Foundation (ASF) under one or more 00003 * contributor license agreements. See the NOTICE file distributed with 00004 * this work for additional information regarding copyright ownership. 00005 * The ASF licenses this file to You under the Apache License, Version 2.0 00006 * (the "License"); you may not use this file except in compliance with 00007 * the License. You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00027 // --------------------------------------------------------------------------- 00028 // Includes 00029 // --------------------------------------------------------------------------- 00030 #include <xercesc/parsers/AbstractDOMParser.hpp> 00031 #include <xercesc/internal/XMLScannerResolver.hpp> 00032 #include <xercesc/internal/ElemStack.hpp> 00033 #include <xercesc/util/XMLUniDefs.hpp> 00034 #include <xercesc/framework/XMLNotationDecl.hpp> 00035 #include <xercesc/framework/XMLValidator.hpp> 00036 #include <xercesc/framework/psvi/PSVIElement.hpp> 00037 #include <xercesc/framework/psvi/PSVIAttribute.hpp> 00038 #include <xercesc/framework/psvi/PSVIAttributeList.hpp> 00039 #include <xercesc/framework/psvi/XSElementDeclaration.hpp> 00040 #include <xercesc/util/IOException.hpp> 00041 #include <xercesc/dom/DOMImplementation.hpp> 00042 #include <xercesc/dom/DOMImplementationRegistry.hpp> 00043 #include <xercesc/dom/DOMElement.hpp> 00044 #include <xercesc/dom/impl/DOMAttrImpl.hpp> 00045 #include <xercesc/dom/impl/DOMAttrNSImpl.hpp> 00046 #include <xercesc/dom/impl/DOMTypeInfoImpl.hpp> 00047 #include <xercesc/dom/impl/DOMCDATASectionImpl.hpp> 00048 #include <xercesc/dom/DOMComment.hpp> 00049 #include <xercesc/dom/impl/DOMTextImpl.hpp> 00050 #include <xercesc/dom/impl/DOMDocumentImpl.hpp> 00051 #include <xercesc/dom/impl/DOMDocumentTypeImpl.hpp> 00052 #include <xercesc/dom/DOMDocumentType.hpp> 00053 #include <xercesc/dom/impl/DOMElementNSImpl.hpp> 00054 #include <xercesc/dom/impl/DOMEntityImpl.hpp> 00055 #include <xercesc/dom/impl/DOMEntityReferenceImpl.hpp> 00056 #include <xercesc/dom/impl/DOMNotationImpl.hpp> 00057 #include <xercesc/dom/DOMNamedNodeMap.hpp> 00058 #include <xercesc/dom/DOMProcessingInstruction.hpp> 00059 #include <xercesc/dom/impl/DOMProcessingInstructionImpl.hpp> 00060 #include <xercesc/dom/impl/DOMNodeIDMap.hpp> 00061 #include <xercesc/dom/impl/DOMCasts.hpp> 00062 #include <xercesc/validators/common/ContentSpecNode.hpp> 00063 #include <xercesc/validators/common/GrammarResolver.hpp> 00064 #include <xercesc/validators/schema/SchemaSymbols.hpp> 00065 #include <xercesc/util/OutOfMemoryException.hpp> 00066 #include <xercesc/xinclude/XIncludeUtils.hpp> 00067 00068 XERCES_CPP_NAMESPACE_BEGIN 00069 00070 00071 // --------------------------------------------------------------------------- 00072 // AbstractDOMParser: Constructors and Destructor 00073 // --------------------------------------------------------------------------- 00074 00075 00076 typedef JanitorMemFunCall<AbstractDOMParser> CleanupType; 00077 typedef JanitorMemFunCall<AbstractDOMParser> ResetInProgressType; 00078 00079 00080 AbstractDOMParser::AbstractDOMParser( XMLValidator* const valToAdopt 00081 , MemoryManager* const manager 00082 , XMLGrammarPool* const gramPool) : 00083 00084 fCreateEntityReferenceNodes(true) 00085 , fIncludeIgnorableWhitespace(true) 00086 , fWithinElement(false) 00087 , fParseInProgress(false) 00088 , fCreateCommentNodes(true) 00089 , fDocumentAdoptedByUser(false) 00090 , fCreateSchemaInfo(false) 00091 , fDoXInclude(false) 00092 , fScanner(0) 00093 , fImplementationFeatures(0) 00094 , fCurrentParent(0) 00095 , fCurrentNode(0) 00096 , fCurrentEntity(0) 00097 , fDocument(0) 00098 , fDocumentType(0) 00099 , fDocumentVector(0) 00100 , fGrammarResolver(0) 00101 , fURIStringPool(0) 00102 , fValidator(valToAdopt) 00103 , fMemoryManager(manager) 00104 , fGrammarPool(gramPool) 00105 , fBufMgr(manager) 00106 , fInternalSubset(fBufMgr.bidOnBuffer()) 00107 , fPSVIHandler(0) 00108 { 00109 CleanupType cleanup(this, &AbstractDOMParser::cleanUp); 00110 00111 try 00112 { 00113 initialize(); 00114 } 00115 catch(const OutOfMemoryException&) 00116 { 00117 // Don't cleanup when out of memory, since executing the 00118 // code can cause problems. 00119 cleanup.release(); 00120 00121 throw; 00122 } 00123 00124 cleanup.release(); 00125 } 00126 00127 00128 AbstractDOMParser::~AbstractDOMParser() 00129 { 00130 cleanUp(); 00131 } 00132 00133 // --------------------------------------------------------------------------- 00134 // AbstractDOMParser: Initialize/CleanUp methods 00135 // --------------------------------------------------------------------------- 00136 void AbstractDOMParser::initialize() 00137 { 00138 // Create grammar resolver and string pool to pass to the scanner 00139 fGrammarResolver = new (fMemoryManager) GrammarResolver(fGrammarPool, fMemoryManager); 00140 fURIStringPool = fGrammarResolver->getStringPool(); 00141 00142 // Create a scanner and tell it what validator to use. Then set us 00143 // as the document event handler so we can fill the DOM document. 00144 fScanner = XMLScannerResolver::getDefaultScanner(fValidator, fGrammarResolver, fMemoryManager); 00145 fScanner->setDocHandler(this); 00146 fScanner->setDocTypeHandler(this); 00147 fScanner->setURIStringPool(fURIStringPool); 00148 00149 this->reset(); 00150 } 00151 00152 void AbstractDOMParser::cleanUp() 00153 { 00154 if (fDocumentVector) 00155 delete fDocumentVector; 00156 00157 if (!fDocumentAdoptedByUser && fDocument) 00158 fDocument->release(); 00159 00160 delete fScanner; 00161 delete fGrammarResolver; 00162 // grammar pool *always* owns this 00163 //delete fURIStringPool; 00164 fMemoryManager->deallocate(fImplementationFeatures); 00165 00166 if (fValidator) 00167 delete fValidator; 00168 } 00169 00170 // --------------------------------------------------------------------------- 00171 // AbstractDOMParser: Utilities 00172 // --------------------------------------------------------------------------- 00173 void AbstractDOMParser::reset() 00174 { 00175 // if fDocument exists already, store the old pointer in the vector for deletion later 00176 if (fDocument && !fDocumentAdoptedByUser) { 00177 if (!fDocumentVector) { 00178 // allocate the vector if not exists yet 00179 fDocumentVector = new (fMemoryManager) RefVectorOf<DOMDocumentImpl>(10, true, fMemoryManager) ; 00180 } 00181 fDocumentVector->addElement(fDocument); 00182 } 00183 00184 fDocument = 0; 00185 resetDocType(); 00186 fCurrentParent = 0; 00187 fCurrentNode = 0; 00188 fCurrentEntity = 0; 00189 fWithinElement = false; 00190 fDocumentAdoptedByUser = false; 00191 fInternalSubset.reset(); 00192 } 00193 00194 00195 void AbstractDOMParser::resetInProgress() 00196 { 00197 fParseInProgress = false; 00198 } 00199 00200 00201 void AbstractDOMParser::resetPool() 00202 { 00203 // We cannot enter here while a regular parse is in progress. 00204 if (fParseInProgress) 00205 ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager); 00206 00207 if (fDocumentVector) 00208 fDocumentVector->removeAllElements(); 00209 00210 if (!fDocumentAdoptedByUser && fDocument) 00211 fDocument->release(); 00212 00213 fDocument = 0; 00214 } 00215 00216 bool AbstractDOMParser::isDocumentAdopted() const 00217 { 00218 return fDocumentAdoptedByUser; 00219 } 00220 00221 DOMDocument* AbstractDOMParser::adoptDocument() 00222 { 00223 fDocumentAdoptedByUser = true; 00224 return fDocument; 00225 } 00226 00227 00228 // --------------------------------------------------------------------------- 00229 // AbstractDOMParser: Getter methods 00230 // --------------------------------------------------------------------------- 00231 DOMDocument* AbstractDOMParser::getDocument() 00232 { 00233 return fDocument; 00234 } 00235 00236 const XMLValidator& AbstractDOMParser::getValidator() const 00237 { 00238 return *fScanner->getValidator(); 00239 } 00240 00241 bool AbstractDOMParser::getDoNamespaces() const 00242 { 00243 return fScanner->getDoNamespaces(); 00244 } 00245 00246 bool AbstractDOMParser::getGenerateSyntheticAnnotations() const 00247 { 00248 return fScanner->getGenerateSyntheticAnnotations(); 00249 } 00250 00251 bool AbstractDOMParser::getValidateAnnotations() const 00252 { 00253 return fScanner->getValidateAnnotations(); 00254 } 00255 00256 bool AbstractDOMParser::getExitOnFirstFatalError() const 00257 { 00258 return fScanner->getExitOnFirstFatal(); 00259 } 00260 00261 bool AbstractDOMParser::getValidationConstraintFatal() const 00262 { 00263 return fScanner->getValidationConstraintFatal(); 00264 } 00265 00266 AbstractDOMParser::ValSchemes AbstractDOMParser::getValidationScheme() const 00267 { 00268 const XMLScanner::ValSchemes scheme = fScanner->getValidationScheme(); 00269 00270 if (scheme == XMLScanner::Val_Always) 00271 return Val_Always; 00272 else if (scheme == XMLScanner::Val_Never) 00273 return Val_Never; 00274 00275 return Val_Auto; 00276 } 00277 00278 bool AbstractDOMParser::getDoSchema() const 00279 { 00280 return fScanner->getDoSchema(); 00281 } 00282 00283 bool AbstractDOMParser::getValidationSchemaFullChecking() const 00284 { 00285 return fScanner->getValidationSchemaFullChecking(); 00286 } 00287 00288 bool AbstractDOMParser::getIdentityConstraintChecking() const 00289 { 00290 return fScanner->getIdentityConstraintChecking(); 00291 } 00292 00293 XMLSize_t AbstractDOMParser::getErrorCount() const 00294 { 00295 return fScanner->getErrorCount(); 00296 } 00297 00298 XMLCh* AbstractDOMParser::getExternalSchemaLocation() const 00299 { 00300 return fScanner->getExternalSchemaLocation(); 00301 } 00302 00303 XMLCh* AbstractDOMParser::getExternalNoNamespaceSchemaLocation() const 00304 { 00305 return fScanner->getExternalNoNamespaceSchemaLocation(); 00306 } 00307 00308 SecurityManager* AbstractDOMParser::getSecurityManager() const 00309 { 00310 return fScanner->getSecurityManager(); 00311 } 00312 00313 // Return it as a reference so that we cn return as void* from getParameter. 00314 // 00315 const XMLSize_t& AbstractDOMParser::getLowWaterMark() const 00316 { 00317 return fScanner->getLowWaterMark(); 00318 } 00319 00320 bool AbstractDOMParser::getLoadExternalDTD() const 00321 { 00322 return fScanner->getLoadExternalDTD(); 00323 } 00324 00325 bool AbstractDOMParser::getLoadSchema() const 00326 { 00327 return fScanner->getLoadSchema(); 00328 } 00329 00330 bool AbstractDOMParser::getCalculateSrcOfs() const 00331 { 00332 return fScanner->getCalculateSrcOfs(); 00333 } 00334 00335 bool AbstractDOMParser::getStandardUriConformant() const 00336 { 00337 return fScanner->getStandardUriConformant(); 00338 } 00339 00340 bool AbstractDOMParser::getIgnoreAnnotations() const 00341 { 00342 return fScanner->getIgnoreAnnotations(); 00343 } 00344 00345 bool AbstractDOMParser::getDisableDefaultEntityResolution() const 00346 { 00347 return fScanner->getDisableDefaultEntityResolution(); 00348 } 00349 00350 bool AbstractDOMParser::getSkipDTDValidation() const 00351 { 00352 return fScanner->getSkipDTDValidation(); 00353 } 00354 00355 bool AbstractDOMParser::getHandleMultipleImports() const 00356 { 00357 return fScanner->getHandleMultipleImports(); 00358 } 00359 00360 // --------------------------------------------------------------------------- 00361 // AbstractDOMParser: Setter methods 00362 // --------------------------------------------------------------------------- 00363 void AbstractDOMParser::setPSVIHandler(PSVIHandler* const handler) 00364 { 00365 fPSVIHandler = handler; 00366 if (fPSVIHandler) { 00367 fScanner->setPSVIHandler(this); 00368 } 00369 else if(!fCreateSchemaInfo) { 00370 fScanner->setPSVIHandler(0); 00371 } 00372 } 00373 00374 00375 void AbstractDOMParser::setDoNamespaces(const bool newState) 00376 { 00377 fScanner->setDoNamespaces(newState); 00378 } 00379 00380 void AbstractDOMParser::setGenerateSyntheticAnnotations(const bool newState) 00381 { 00382 fScanner->setGenerateSyntheticAnnotations(newState); 00383 } 00384 00385 void AbstractDOMParser::setValidateAnnotations(const bool newState) 00386 { 00387 fScanner->setValidateAnnotations(newState); 00388 } 00389 00390 void AbstractDOMParser::setExitOnFirstFatalError(const bool newState) 00391 { 00392 fScanner->setExitOnFirstFatal(newState); 00393 } 00394 00395 void AbstractDOMParser::setValidationConstraintFatal(const bool newState) 00396 { 00397 fScanner->setValidationConstraintFatal(newState); 00398 } 00399 00400 void AbstractDOMParser::setValidationScheme(const ValSchemes newScheme) 00401 { 00402 if (newScheme == Val_Never) 00403 fScanner->setValidationScheme(XMLScanner::Val_Never); 00404 else if (newScheme == Val_Always) 00405 fScanner->setValidationScheme(XMLScanner::Val_Always); 00406 else 00407 fScanner->setValidationScheme(XMLScanner::Val_Auto); 00408 } 00409 00410 void AbstractDOMParser::setDoSchema(const bool newState) 00411 { 00412 fScanner->setDoSchema(newState); 00413 } 00414 00415 void AbstractDOMParser::setValidationSchemaFullChecking(const bool schemaFullChecking) 00416 { 00417 fScanner->setValidationSchemaFullChecking(schemaFullChecking); 00418 } 00419 00420 void AbstractDOMParser::setIdentityConstraintChecking(const bool identityConstraintChecking) 00421 { 00422 fScanner->setIdentityConstraintChecking(identityConstraintChecking); 00423 } 00424 00425 void AbstractDOMParser::setExternalSchemaLocation(const XMLCh* const schemaLocation) 00426 { 00427 fScanner->setExternalSchemaLocation(schemaLocation); 00428 } 00429 void AbstractDOMParser::setExternalNoNamespaceSchemaLocation(const XMLCh* const noNamespaceSchemaLocation) 00430 { 00431 fScanner->setExternalNoNamespaceSchemaLocation(noNamespaceSchemaLocation); 00432 } 00433 00434 void AbstractDOMParser::setExternalSchemaLocation(const char* const schemaLocation) 00435 { 00436 fScanner->setExternalSchemaLocation(schemaLocation); 00437 } 00438 void AbstractDOMParser::setExternalNoNamespaceSchemaLocation(const char* const noNamespaceSchemaLocation) 00439 { 00440 fScanner->setExternalNoNamespaceSchemaLocation(noNamespaceSchemaLocation); 00441 } 00442 00443 void AbstractDOMParser::setSecurityManager(SecurityManager* const securityManager) 00444 { 00445 // since this could impact various components, don't permit it to change 00446 // during a parse 00447 if (fParseInProgress) 00448 ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager); 00449 00450 fScanner->setSecurityManager(securityManager); 00451 } 00452 00453 void AbstractDOMParser::setLowWaterMark(XMLSize_t lwm) 00454 { 00455 fScanner->setLowWaterMark(lwm); 00456 } 00457 00458 void AbstractDOMParser::setLoadExternalDTD(const bool newState) 00459 { 00460 fScanner->setLoadExternalDTD(newState); 00461 } 00462 00463 void AbstractDOMParser::setLoadSchema(const bool newState) 00464 { 00465 fScanner->setLoadSchema(newState); 00466 } 00467 00468 void AbstractDOMParser::setCalculateSrcOfs(const bool newState) 00469 { 00470 fScanner->setCalculateSrcOfs(newState); 00471 } 00472 00473 void AbstractDOMParser::setStandardUriConformant(const bool newState) 00474 { 00475 fScanner->setStandardUriConformant(newState); 00476 } 00477 00478 void AbstractDOMParser::useScanner(const XMLCh* const scannerName) 00479 { 00480 XMLScanner* tempScanner = XMLScannerResolver::resolveScanner 00481 ( 00482 scannerName 00483 , fValidator 00484 , fGrammarResolver 00485 , fMemoryManager 00486 ); 00487 00488 if (tempScanner) { 00489 00490 tempScanner->setParseSettings(fScanner); 00491 tempScanner->setURIStringPool(fURIStringPool); 00492 delete fScanner; 00493 fScanner = tempScanner; 00494 } 00495 } 00496 00497 void AbstractDOMParser::setCreateSchemaInfo(const bool create) 00498 { 00499 fCreateSchemaInfo = create; 00500 if(fCreateSchemaInfo) 00501 fScanner->setPSVIHandler(this); 00502 else if(!fPSVIHandler) 00503 fScanner->setPSVIHandler(0); 00504 } 00505 00506 void AbstractDOMParser::setIgnoreAnnotations(const bool newValue) 00507 { 00508 fScanner->setIgnoreAnnotations(newValue); 00509 } 00510 00511 void AbstractDOMParser::setDisableDefaultEntityResolution(const bool newValue) 00512 { 00513 fScanner->setDisableDefaultEntityResolution(newValue); 00514 } 00515 00516 void AbstractDOMParser::setSkipDTDValidation(const bool newValue) 00517 { 00518 fScanner->setSkipDTDValidation(newValue); 00519 } 00520 00521 void AbstractDOMParser::setHandleMultipleImports(const bool newValue) 00522 { 00523 fScanner->setHandleMultipleImports(newValue); 00524 } 00525 00526 void AbstractDOMParser::setDocument(DOMDocument* toSet) 00527 { 00528 fDocument = (DOMDocumentImpl *)toSet; 00529 } 00530 00531 // --------------------------------------------------------------------------- 00532 // AbstractDOMParser: Parsing methods 00533 // --------------------------------------------------------------------------- 00534 void AbstractDOMParser::parse(const InputSource& source) 00535 { 00536 // Avoid multiple entrance 00537 if (fParseInProgress) 00538 ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager); 00539 00540 ResetInProgressType resetInProgress(this, &AbstractDOMParser::resetInProgress); 00541 00542 try 00543 { 00544 fParseInProgress = true; 00545 fScanner->scanDocument(source); 00546 00547 if (fDoXInclude && getErrorCount()==0){ 00548 DOMDocument *doc = getDocument(); 00549 // after XInclude, the document must be normalized 00550 if(doc) 00551 doc->normalizeDocument(); 00552 } 00553 } 00554 catch(const OutOfMemoryException&) 00555 { 00556 resetInProgress.release(); 00557 00558 throw; 00559 } 00560 } 00561 00562 void AbstractDOMParser::parse(const XMLCh* const systemId) 00563 { 00564 // Avoid multiple entrance 00565 if (fParseInProgress) 00566 ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager); 00567 00568 ResetInProgressType resetInProgress(this, &AbstractDOMParser::resetInProgress); 00569 00570 try 00571 { 00572 fParseInProgress = true; 00573 fScanner->scanDocument(systemId); 00574 00575 if (fDoXInclude && getErrorCount()==0){ 00576 DOMDocument *doc = getDocument(); 00577 // after XInclude, the document must be normalized 00578 if(doc) 00579 doc->normalizeDocument(); 00580 } 00581 } 00582 catch(const OutOfMemoryException&) 00583 { 00584 resetInProgress.release(); 00585 00586 throw; 00587 } 00588 } 00589 00590 void AbstractDOMParser::parse(const char* const systemId) 00591 { 00592 // Avoid multiple entrance 00593 if (fParseInProgress) 00594 ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager); 00595 00596 ResetInProgressType resetInProgress(this, &AbstractDOMParser::resetInProgress); 00597 00598 try 00599 { 00600 fParseInProgress = true; 00601 fScanner->scanDocument(systemId); 00602 00603 if (fDoXInclude && getErrorCount()==0){ 00604 DOMDocument *doc = getDocument(); 00605 // after XInclude, the document must be normalized 00606 if(doc) 00607 doc->normalizeDocument(); 00608 } 00609 } 00610 catch(const OutOfMemoryException&) 00611 { 00612 resetInProgress.release(); 00613 00614 throw; 00615 } 00616 } 00617 00618 00619 00620 // --------------------------------------------------------------------------- 00621 // AbstractDOMParser: Progressive parse methods 00622 // --------------------------------------------------------------------------- 00623 bool AbstractDOMParser::parseFirst( const XMLCh* const systemId 00624 , XMLPScanToken& toFill) 00625 { 00626 // 00627 // Avoid multiple entrance. We cannot enter here while a regular parse 00628 // is in progress. 00629 // 00630 if (fParseInProgress) 00631 ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager); 00632 00633 return fScanner->scanFirst(systemId, toFill); 00634 } 00635 00636 bool AbstractDOMParser::parseFirst( const char* const systemId 00637 , XMLPScanToken& toFill) 00638 { 00639 // 00640 // Avoid multiple entrance. We cannot enter here while a regular parse 00641 // is in progress. 00642 // 00643 if (fParseInProgress) 00644 ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager); 00645 00646 return fScanner->scanFirst(systemId, toFill); 00647 } 00648 00649 bool AbstractDOMParser::parseFirst( const InputSource& source 00650 , XMLPScanToken& toFill) 00651 { 00652 // 00653 // Avoid multiple entrance. We cannot enter here while a regular parse 00654 // is in progress. 00655 // 00656 if (fParseInProgress) 00657 ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager); 00658 00659 return fScanner->scanFirst(source, toFill); 00660 } 00661 00662 bool AbstractDOMParser::parseNext(XMLPScanToken& token) 00663 { 00664 return fScanner->scanNext(token); 00665 } 00666 00667 void AbstractDOMParser::parseReset(XMLPScanToken& token) 00668 { 00669 // Reset the scanner, and then reset the parser 00670 fScanner->scanReset(token); 00671 reset(); 00672 } 00673 00674 00675 // --------------------------------------------------------------------------- 00676 // AbstractDOMParser: Implementation of PSVIHandler interface 00677 // --------------------------------------------------------------------------- 00678 void AbstractDOMParser::handleElementPSVI(const XMLCh* const localName 00679 , const XMLCh* const uri 00680 , PSVIElement * elementInfo) 00681 { 00682 // associate the info now; if the user wants, she can override what we did 00683 if(fCreateSchemaInfo) 00684 { 00685 DOMTypeInfoImpl* typeInfo=new (getDocument()) DOMTypeInfoImpl(); 00686 typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Validity, elementInfo->getValidity()); 00687 typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Validation_Attempted, elementInfo->getValidationAttempted()); 00688 if(elementInfo->getTypeDefinition()) 00689 { 00690 typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Type, elementInfo->getTypeDefinition()->getTypeCategory()); 00691 typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Anonymous, elementInfo->getTypeDefinition()->getAnonymous()); 00692 typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Namespace, 00693 fDocument->getPooledString(elementInfo->getTypeDefinition()->getNamespace())); 00694 typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Name, 00695 fDocument->getPooledString(elementInfo->getTypeDefinition()->getName())); 00696 } 00697 else if(elementInfo->getValidity()==PSVIItem::VALIDITY_VALID) 00698 { 00699 // if we are valid but we don't have a type validator, we are xs:anyType 00700 typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Type, XSTypeDefinition::COMPLEX_TYPE); 00701 typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Anonymous, false); 00702 typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Namespace, SchemaSymbols::fgURI_SCHEMAFORSCHEMA); 00703 typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Name, SchemaSymbols::fgATTVAL_ANYTYPE); 00704 } 00705 if(elementInfo->getMemberTypeDefinition()) 00706 { 00707 typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Member_Type_Definition_Anonymous, elementInfo->getMemberTypeDefinition()->getAnonymous()); 00708 typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Member_Type_Definition_Namespace, 00709 fDocument->getPooledString(elementInfo->getMemberTypeDefinition()->getNamespace())); 00710 typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Member_Type_Definition_Name, 00711 fDocument->getPooledString(elementInfo->getMemberTypeDefinition()->getName())); 00712 } 00713 if(elementInfo->getElementDeclaration()) 00714 typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Nil, elementInfo->getElementDeclaration()->getNillable()); 00715 typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Schema_Default, fDocument->getPooledString(elementInfo->getSchemaDefault())); 00716 typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Schema_Normalized_Value, fDocument->getPooledString(elementInfo->getSchemaNormalizedValue())); 00717 typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Schema_Specified, true); 00718 ((DOMElementNSImpl*)fCurrentParent)->setSchemaTypeInfo(typeInfo); 00719 } 00720 if(fPSVIHandler) 00721 fPSVIHandler->handleElementPSVI(localName, uri, elementInfo); 00722 } 00723 00724 void AbstractDOMParser::handlePartialElementPSVI(const XMLCh* const localName 00725 , const XMLCh* const uri 00726 , PSVIElement * elementInfo) 00727 { 00728 if(fPSVIHandler) 00729 fPSVIHandler->handlePartialElementPSVI(localName, uri, elementInfo); 00730 } 00731 00732 void AbstractDOMParser::handleAttributesPSVI( const XMLCh* const localName 00733 , const XMLCh* const uri 00734 , PSVIAttributeList * psviAttributes) 00735 { 00736 if(fCreateSchemaInfo) 00737 { 00738 for (XMLSize_t index=0; index < psviAttributes->getLength(); index++) { 00739 XERCES_CPP_NAMESPACE_QUALIFIER PSVIAttribute *attrInfo=psviAttributes->getAttributePSVIAtIndex(index); 00740 XERCES_CPP_NAMESPACE_QUALIFIER DOMNode* pAttrNode=fCurrentNode->getAttributes()->getNamedItemNS(psviAttributes->getAttributeNamespaceAtIndex(index), 00741 psviAttributes->getAttributeNameAtIndex(index)); 00742 if(pAttrNode!=NULL) 00743 { 00744 DOMTypeInfoImpl* typeInfo=new (getDocument()) DOMTypeInfoImpl(); 00745 typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Validity, attrInfo->getValidity()); 00746 typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Validation_Attempted, attrInfo->getValidationAttempted()); 00747 if(attrInfo->getTypeDefinition()) 00748 { 00749 typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Type, XSTypeDefinition::SIMPLE_TYPE); 00750 typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Anonymous, attrInfo->getTypeDefinition()->getAnonymous()); 00751 typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Namespace, 00752 fDocument->getPooledString(attrInfo->getTypeDefinition()->getNamespace())); 00753 typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Name, 00754 fDocument->getPooledString(attrInfo->getTypeDefinition()->getName())); 00755 } 00756 else if(attrInfo->getValidity()==PSVIItem::VALIDITY_VALID) 00757 { 00758 // if we are valid but we don't have a type validator, we are xs:anySimpleType 00759 typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Type, XSTypeDefinition::SIMPLE_TYPE); 00760 typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Anonymous, false); 00761 typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Namespace, SchemaSymbols::fgURI_SCHEMAFORSCHEMA); 00762 typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Name, SchemaSymbols::fgDT_ANYSIMPLETYPE); 00763 } 00764 if(attrInfo->getMemberTypeDefinition()) 00765 { 00766 typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Member_Type_Definition_Anonymous, attrInfo->getMemberTypeDefinition()->getAnonymous()); 00767 typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Member_Type_Definition_Namespace, 00768 fDocument->getPooledString(attrInfo->getMemberTypeDefinition()->getNamespace())); 00769 typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Member_Type_Definition_Name, 00770 fDocument->getPooledString(attrInfo->getMemberTypeDefinition()->getName())); 00771 } 00772 typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Schema_Default, fDocument->getPooledString(attrInfo->getSchemaDefault())); 00773 typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Schema_Normalized_Value, fDocument->getPooledString(attrInfo->getSchemaNormalizedValue())); 00774 typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Schema_Specified, true); 00775 ((DOMAttrImpl*)pAttrNode)->setSchemaTypeInfo(typeInfo); 00776 } 00777 } 00778 } 00779 // associate the info now; if the user wants, she can override what we did 00780 if(fPSVIHandler) 00781 fPSVIHandler->handleAttributesPSVI(localName, uri, psviAttributes); 00782 } 00783 00784 // --------------------------------------------------------------------------- 00785 // AbstractDOMParser: Implementation of XMLDocumentHandler interface 00786 // --------------------------------------------------------------------------- 00787 void AbstractDOMParser::docCharacters( const XMLCh* const chars 00788 , const XMLSize_t length 00789 , const bool cdataSection) 00790 { 00791 // Ignore chars outside of content 00792 if (!fWithinElement) 00793 return; 00794 00795 if (cdataSection == true) 00796 { 00797 DOMCDATASection *node = createCDATASection (chars, length); 00798 castToParentImpl (fCurrentParent)->appendChildFast (node); 00799 fCurrentNode = node; 00800 } 00801 else 00802 { 00803 if (fCurrentNode->getNodeType() == DOMNode::TEXT_NODE) 00804 { 00805 DOMTextImpl *node = (DOMTextImpl*)fCurrentNode; 00806 node->appendData(chars, length); 00807 } 00808 else 00809 { 00810 DOMText *node = createText (chars, length); 00811 castToParentImpl (fCurrentParent)->appendChildFast (node); 00812 fCurrentNode = node; 00813 } 00814 } 00815 } 00816 00817 00818 void AbstractDOMParser::docComment(const XMLCh* const comment) 00819 { 00820 if (fCreateCommentNodes) { 00821 DOMComment *dcom = fDocument->createComment(comment); 00822 castToParentImpl (fCurrentParent)->appendChildFast (dcom); 00823 fCurrentNode = dcom; 00824 } 00825 } 00826 00827 00828 void AbstractDOMParser::docPI( const XMLCh* const target 00829 , const XMLCh* const data) 00830 { 00831 DOMProcessingInstruction *pi = fDocument->createProcessingInstruction 00832 ( 00833 target 00834 , data 00835 ); 00836 castToParentImpl (fCurrentParent)->appendChildFast (pi); 00837 fCurrentNode = pi; 00838 } 00839 00840 00841 void AbstractDOMParser::endEntityReference(const XMLEntityDecl&) 00842 { 00843 if (!fCreateEntityReferenceNodes) 00844 return; 00845 00846 DOMEntityReferenceImpl *erImpl = 0; 00847 00848 if (fCurrentParent->getNodeType() == DOMNode::ENTITY_REFERENCE_NODE) 00849 erImpl = (DOMEntityReferenceImpl *) fCurrentParent; 00850 00851 fCurrentNode = fCurrentParent; 00852 fCurrentParent = fCurrentNode->getParentNode (); 00853 00854 // When the document is invalid but we continue parsing, we may 00855 // end up seeing more 'end' events than the 'start' ones. 00856 // 00857 if (fCurrentParent == 0 && fDocument != 0) 00858 { 00859 fCurrentNode = fDocument->getDocumentElement (); 00860 fCurrentParent = fCurrentNode; 00861 } 00862 00863 if (erImpl) 00864 erImpl->setReadOnly(true, true); 00865 } 00866 00867 00868 void AbstractDOMParser::endElement( const XMLElementDecl& 00869 , const unsigned int 00870 , const bool 00871 , const XMLCh* const) 00872 { 00873 fCurrentNode = fCurrentParent; 00874 fCurrentParent = fCurrentNode->getParentNode (); 00875 00876 // When the document is invalid but we continue parsing, we may 00877 // end up seeing more 'end' events than the 'start' ones. 00878 // 00879 if (fCurrentParent == 0 && fDocument != 0) 00880 { 00881 fCurrentNode = fDocument->getDocumentElement (); 00882 fCurrentParent = fCurrentNode; 00883 } 00884 00885 // If we've hit the end of content, clear the flag. 00886 // 00887 if (fCurrentParent == fDocument) 00888 fWithinElement = false; 00889 00890 if(fDoXInclude && 00891 (XIncludeUtils::isXIIncludeDOMNode(fCurrentNode) || 00892 ((XIncludeUtils::isXIFallbackDOMNode(fCurrentNode) && 00893 !XMLString::equals(fCurrentParent->getNamespaceURI(), XIncludeUtils::fgXIIIncludeNamespaceURI))))) 00894 { 00895 XIncludeUtils xiu((XMLErrorReporter *) this); 00896 // process the XInclude node, then update the fCurrentNode with the new content 00897 if(xiu.parseDOMNodeDoingXInclude(fCurrentNode, fDocument, getScanner()->getEntityHandler())) 00898 fCurrentNode = fCurrentParent->getLastChild(); 00899 } 00900 } 00901 00902 00903 void AbstractDOMParser::ignorableWhitespace( const XMLCh* const chars 00904 , const XMLSize_t length 00905 , const bool) 00906 { 00907 // Ignore chars before the root element 00908 if (!fWithinElement || !fIncludeIgnorableWhitespace) 00909 return; 00910 00911 // revisit. Not safe to slam in a null like this. 00912 XMLCh savedChar = chars[length]; 00913 XMLCh *ncChars = (XMLCh *)chars; // cast off const 00914 ncChars[length] = chNull; 00915 00916 if (fCurrentNode->getNodeType() == DOMNode::TEXT_NODE) 00917 { 00918 DOMText *node = (DOMText *)fCurrentNode; 00919 node->appendData(chars); 00920 } 00921 else 00922 { 00923 DOMTextImpl *node = (DOMTextImpl *)fDocument->createTextNode(chars); 00924 node->setIgnorableWhitespace(true); 00925 castToParentImpl (fCurrentParent)->appendChildFast (node); 00926 00927 fCurrentNode = node; 00928 } 00929 ncChars[length] = savedChar; 00930 } 00931 00932 00933 void AbstractDOMParser::resetDocument() 00934 { 00935 // 00936 // The reset methods are called before a new parse event occurs. 00937 // Reset this parsers state to clear out anything that may be left 00938 // from a previous use, in particular the DOM document itself. 00939 // 00940 this->reset(); 00941 } 00942 00943 00944 void AbstractDOMParser::startDocument() 00945 { 00946 if(fImplementationFeatures == 0) 00947 fDocument = (DOMDocumentImpl *)DOMImplementation::getImplementation()->createDocument(fMemoryManager); 00948 else 00949 fDocument = (DOMDocumentImpl *)DOMImplementationRegistry::getDOMImplementation(fImplementationFeatures)->createDocument(fMemoryManager); 00950 00951 // Just set the document as the current parent and current node 00952 fCurrentParent = fDocument; 00953 fCurrentNode = fDocument; 00954 // set DOM error checking off 00955 fDocument->setErrorChecking(false); 00956 fDocument->setDocumentURI(fScanner->getLocator()->getSystemId()); 00957 fDocument->setInputEncoding(fScanner->getReaderMgr()->getCurrentEncodingStr()); 00958 } 00959 00960 00961 void AbstractDOMParser::endDocument() 00962 { 00963 // set DOM error checking back on 00964 fDocument->setErrorChecking(true); 00965 00966 // DOM L2 does not support editing DocumentType nodes 00967 if (fDocumentType && fScanner -> getDoNamespaces()) 00968 fDocumentType->setReadOnly(true, true); 00969 } 00970 00971 00972 void AbstractDOMParser::startElement(const XMLElementDecl& elemDecl 00973 , const unsigned int urlId 00974 , const XMLCh* const elemPrefix 00975 , const RefVectorOf<XMLAttr>& attrList 00976 , const XMLSize_t attrCount 00977 , const bool isEmpty 00978 , const bool isRoot) 00979 { 00980 DOMElement *elem; 00981 DOMElementImpl *elemImpl; 00982 const XMLCh* namespaceURI = 0; 00983 bool doNamespaces = fScanner->getDoNamespaces(); 00984 00985 // Create the element name. Here we are going to bypass the 00986 // DOMDocument::createElement() interface and instantiate the 00987 // required types directly in order to avoid name checking 00988 // overhead. 00989 // 00990 if (doNamespaces) 00991 { 00992 //DOM Level 2, doNamespaces on 00993 // 00994 const XMLCh* localName = elemDecl.getBaseName(); 00995 00996 if (urlId != fScanner->getEmptyNamespaceId()) { //TagName has a prefix 00997 00998 namespaceURI = fScanner->getURIText(urlId); //get namespaceURI 00999 01000 if (elemPrefix && *elemPrefix) 01001 { 01002 XMLBufBid elemQName(&fBufMgr); 01003 01004 elemQName.set(elemPrefix); 01005 elemQName.append(chColon); 01006 elemQName.append(localName); 01007 01008 elem = createElementNS ( 01009 namespaceURI, elemPrefix, localName, elemQName.getRawBuffer()); 01010 } 01011 else 01012 elem = createElementNS (namespaceURI, 0, localName, localName); 01013 } 01014 else 01015 elem = createElementNS (namespaceURI, 0, localName, localName); 01016 } 01017 else 01018 { //DOM Level 1 01019 elem = createElement (elemDecl.getFullName()); 01020 } 01021 01022 elemImpl = (DOMElementImpl *) elem; 01023 01024 if (attrCount) 01025 { 01026 unsigned int xmlnsNSId = fScanner->getXMLNSNamespaceId(); 01027 unsigned int emptyNSId = fScanner->getEmptyNamespaceId(); 01028 01029 DOMAttrMapImpl* map = elemImpl->fAttributes; 01030 map->reserve (attrCount); 01031 01032 for (XMLSize_t index = 0; index < attrCount; ++index) 01033 { 01034 const XMLAttr* oneAttrib = attrList.elementAt(index); 01035 DOMAttrImpl *attr = 0; 01036 01037 if (doNamespaces) 01038 { 01039 //DOM Level 2, doNamespaces on 01040 // 01041 unsigned int attrURIId = oneAttrib->getURIId(); 01042 const XMLCh* localName = oneAttrib->getName(); 01043 const XMLCh* prefix = oneAttrib->getPrefix(); 01044 namespaceURI = 0; 01045 01046 if ((prefix==0 || *prefix==0) && XMLString::equals(localName, XMLUni::fgXMLNSString)) 01047 { 01048 // xmlns=... 01049 attrURIId = xmlnsNSId; 01050 } 01051 if (attrURIId != emptyNSId) 01052 { 01053 //TagName has a prefix 01054 namespaceURI = fScanner->getURIText(attrURIId); 01055 } 01056 01057 attr = (DOMAttrImpl*) createAttrNS (namespaceURI, 01058 prefix, 01059 localName, 01060 oneAttrib->getQName()); 01061 01062 map->setNamedItemNSFast(attr); 01063 } 01064 else 01065 { 01066 attr = (DOMAttrImpl*) createAttr (oneAttrib->getName()); 01067 map->setNamedItemFast(attr); 01068 } 01069 01070 attr->setValueFast(oneAttrib->getValue()); 01071 01072 // Attributes of type ID. If this is one, add it to the hashtable of IDs 01073 // that is constructed for use by GetElementByID(). 01074 // 01075 if (oneAttrib->getType()==XMLAttDef::ID) 01076 { 01077 if (fDocument->fNodeIDMap == 0) 01078 fDocument->fNodeIDMap = new (fDocument) DOMNodeIDMap(500, fDocument); 01079 fDocument->fNodeIDMap->add(attr); 01080 attr->fNode.isIdAttr(true); 01081 } 01082 01083 attr->setSpecified(oneAttrib->getSpecified()); 01084 01085 // store DTD validation information 01086 if(fCreateSchemaInfo) 01087 { 01088 switch(oneAttrib->getType()) 01089 { 01090 case XMLAttDef::CData: attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedCDATAAttribute); break; 01091 case XMLAttDef::ID: attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDAttribute); break; 01092 case XMLAttDef::IDRef: attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDREFAttribute); break; 01093 case XMLAttDef::IDRefs: attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDREFSAttribute); break; 01094 case XMLAttDef::Entity: attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENTITYAttribute); break; 01095 case XMLAttDef::Entities: attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENTITIESAttribute); break; 01096 case XMLAttDef::NmToken: attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNMTOKENAttribute); break; 01097 case XMLAttDef::NmTokens: attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNMTOKENSAttribute); break; 01098 case XMLAttDef::Notation: attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNOTATIONAttribute); break; 01099 case XMLAttDef::Enumeration: attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENUMERATIONAttribute); break; 01100 default: attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdNotValidatedAttribute); break; 01101 } 01102 } 01103 } 01104 } 01105 01106 //Set up the default attributes if any. 01107 // 01108 if (elemDecl.hasAttDefs()) 01109 { 01110 XMLAttDefList* defAttrs = &elemDecl.getAttDefList(); 01111 XMLAttDef* attr = 0; 01112 DOMAttrImpl * insertAttr = 0; 01113 01114 for(XMLSize_t i=0; i<defAttrs->getAttDefCount(); i++) 01115 { 01116 attr = &defAttrs->getAttDef(i); 01117 01118 const XMLAttDef::DefAttTypes defType = attr->getDefaultType(); 01119 if ((defType == XMLAttDef::Default) 01120 || (defType == XMLAttDef::Fixed)) 01121 { 01122 01123 if (doNamespaces) 01124 { 01125 // DOM Level 2 wants all namespace declaration attributes 01126 // to be bound to "http://www.w3.org/2000/xmlns/" 01127 // So as long as the XML parser doesn't do it, it needs to 01128 // be done here. 01129 const XMLCh* qualifiedName = attr->getFullName(); 01130 XMLBufBid bbPrefixQName(&fBufMgr); 01131 XMLBuffer& prefixBuf = bbPrefixQName.getBuffer(); 01132 int colonPos = -1; 01133 unsigned int uriId = fScanner->resolveQName(qualifiedName, prefixBuf, ElemStack::Mode_Attribute, colonPos); 01134 01135 const XMLCh* namespaceURI = 0; 01136 if (XMLString::equals(qualifiedName, XMLUni::fgXMLNSString)) //for xmlns=... 01137 uriId = fScanner->getXMLNSNamespaceId(); 01138 if (uriId != fScanner->getEmptyNamespaceId()) { //TagName has a prefix 01139 namespaceURI = fScanner->getURIText(uriId); 01140 } 01141 01142 insertAttr = (DOMAttrImpl *) fDocument->createAttributeNS(namespaceURI, // NameSpaceURI 01143 qualifiedName); // qualified name 01144 01145 DOMAttr* remAttr = elemImpl->setDefaultAttributeNodeNS(insertAttr); 01146 if (remAttr) 01147 remAttr->release(); 01148 } 01149 else 01150 { 01151 // Namespaces is turned off... 01152 insertAttr = (DOMAttrImpl *) fDocument->createAttribute(attr->getFullName()); 01153 01154 DOMNode* remAttr = elemImpl->setDefaultAttributeNode(insertAttr); 01155 if (remAttr) 01156 remAttr->release(); 01157 } 01158 //need to do this before the get as otherwise we overwrite any value in the attr 01159 if (attr->getValue() != 0) 01160 { 01161 insertAttr->setValueFast(attr->getValue()); 01162 insertAttr->setSpecified(false); 01163 } 01164 01165 // store DTD validation information 01166 if(fCreateSchemaInfo) 01167 { 01168 switch(attr->getType()) 01169 { 01170 case XMLAttDef::CData: insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedCDATAAttribute); break; 01171 case XMLAttDef::ID: insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDAttribute); break; 01172 case XMLAttDef::IDRef: insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDREFAttribute); break; 01173 case XMLAttDef::IDRefs: insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDREFSAttribute); break; 01174 case XMLAttDef::Entity: insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENTITYAttribute); break; 01175 case XMLAttDef::Entities: insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENTITIESAttribute); break; 01176 case XMLAttDef::NmToken: insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNMTOKENAttribute); break; 01177 case XMLAttDef::NmTokens: insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNMTOKENSAttribute); break; 01178 case XMLAttDef::Notation: insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNOTATIONAttribute); break; 01179 case XMLAttDef::Enumeration: insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENUMERATIONAttribute); break; 01180 default: insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdNotValidatedAttribute); break; 01181 } 01182 } 01183 } 01184 01185 insertAttr = 0; 01186 attr->reset(); 01187 } 01188 } 01189 01190 if (fCurrentParent != fDocument) 01191 castToParentImpl (fCurrentParent)->appendChildFast (elem); 01192 else 01193 fCurrentParent->appendChild (elem); 01194 01195 fCurrentParent = elem; 01196 fCurrentNode = elem; 01197 fWithinElement = true; 01198 01199 // If an empty element, do end right now (no endElement() will be called) 01200 if (isEmpty) 01201 endElement(elemDecl, urlId, isRoot, elemPrefix); 01202 } 01203 01204 01205 void AbstractDOMParser::startEntityReference(const XMLEntityDecl& entDecl) 01206 { 01207 const XMLCh * entName = entDecl.getName(); 01208 DOMNamedNodeMap *entities = fDocumentType->getEntities(); 01209 DOMEntityImpl* entity = (DOMEntityImpl*)entities->getNamedItem(entName); 01210 if (entity) 01211 entity->setInputEncoding(fScanner->getReaderMgr()->getCurrentEncodingStr()); 01212 fCurrentEntity = entity; 01213 01214 01215 // Following line has been moved up so that erImpl is only declared 01216 // and used if create entity ref flag is true 01217 if (fCreateEntityReferenceNodes == true) { 01218 DOMEntityReference *er = fDocument->createEntityReferenceByParser(entName); 01219 01220 //set the readOnly flag to false before appending node, will be reset 01221 // in endEntityReference 01222 DOMEntityReferenceImpl *erImpl = (DOMEntityReferenceImpl *) er; 01223 erImpl->setReadOnly(false, true); 01224 01225 castToParentImpl (fCurrentParent)->appendChildFast (er); 01226 01227 fCurrentParent = er; 01228 fCurrentNode = er; 01229 01230 // this entityRef needs to be stored in Entity map too. 01231 // We'd decide later whether the entity nodes should be created by a 01232 // separated method in parser or not. For now just stick it in if 01233 // the ref nodes are created 01234 if (entity) 01235 entity->setEntityRef(er); 01236 } 01237 } 01238 01239 01240 void AbstractDOMParser::XMLDecl(const XMLCh* const version 01241 , const XMLCh* const encoding 01242 , const XMLCh* const standalone 01243 , const XMLCh* const actualEncStr) 01244 { 01245 fDocument->setXmlStandalone(XMLString::equals(XMLUni::fgYesString, standalone)); 01246 fDocument->setXmlVersion(version); 01247 fDocument->setXmlEncoding(encoding); 01248 fDocument->setInputEncoding(actualEncStr); 01249 } 01250 01251 // --------------------------------------------------------------------------- 01252 // AbstractDOMParser: Helper methods 01253 // --------------------------------------------------------------------------- 01254 01255 //doctypehandler interfaces 01256 void AbstractDOMParser::attDef 01257 ( 01258 const DTDElementDecl& elemDecl 01259 , const DTDAttDef& attDef 01260 , const bool 01261 ) 01262 { 01263 if (fDocumentType->isIntSubsetReading()) 01264 { 01265 if (elemDecl.hasAttDefs()) 01266 { 01267 fInternalSubset.append(attDef.getFullName()); 01268 01269 // Get the type and display it 01270 const XMLAttDef::AttTypes type = attDef.getType(); 01271 switch(type) 01272 { 01273 case XMLAttDef::CData : 01274 fInternalSubset.append(chSpace); 01275 fInternalSubset.append(XMLUni::fgCDATAString); 01276 break; 01277 case XMLAttDef::ID : 01278 fInternalSubset.append(chSpace); 01279 fInternalSubset.append(XMLUni::fgIDString); 01280 break; 01281 case XMLAttDef::IDRef : 01282 fInternalSubset.append(chSpace); 01283 fInternalSubset.append(XMLUni::fgIDRefString); 01284 break; 01285 case XMLAttDef::IDRefs : 01286 fInternalSubset.append(chSpace); 01287 fInternalSubset.append(XMLUni::fgIDRefsString); 01288 break; 01289 case XMLAttDef::Entity : 01290 fInternalSubset.append(chSpace); 01291 fInternalSubset.append(XMLUni::fgEntityString); 01292 break; 01293 case XMLAttDef::Entities : 01294 fInternalSubset.append(chSpace); 01295 fInternalSubset.append(XMLUni::fgEntitiesString); 01296 break; 01297 case XMLAttDef::NmToken : 01298 fInternalSubset.append(chSpace); 01299 fInternalSubset.append(XMLUni::fgNmTokenString); 01300 break; 01301 case XMLAttDef::NmTokens : 01302 fInternalSubset.append(chSpace); 01303 fInternalSubset.append(XMLUni::fgNmTokensString); 01304 break; 01305 01306 case XMLAttDef::Notation : 01307 fInternalSubset.append(chSpace); 01308 fInternalSubset.append(XMLUni::fgNotationString); 01309 break; 01310 01311 case XMLAttDef::Enumeration : 01312 { 01313 fInternalSubset.append(chSpace); 01314 const XMLCh* enumString = attDef.getEnumeration(); 01315 XMLSize_t length = XMLString::stringLen(enumString); 01316 if (length > 0) { 01317 01318 fInternalSubset.append(chOpenParen ); 01319 for(XMLSize_t i=0; i<length; i++) { 01320 if (enumString[i] == chSpace) 01321 fInternalSubset.append(chPipe); 01322 else 01323 fInternalSubset.append(enumString[i]); 01324 } 01325 fInternalSubset.append(chCloseParen); 01326 } 01327 } 01328 break; 01329 default: 01330 // remaining types don't belong to a DTD 01331 break; 01332 } 01333 //get te default types of the attlist 01334 const XMLAttDef::DefAttTypes def = attDef.getDefaultType(); 01335 switch(def) 01336 { 01337 case XMLAttDef::Required : 01338 fInternalSubset.append(chSpace); 01339 fInternalSubset.append(XMLUni::fgRequiredString); 01340 break; 01341 case XMLAttDef::Implied : 01342 fInternalSubset.append(chSpace); 01343 fInternalSubset.append(XMLUni::fgImpliedString); 01344 break; 01345 case XMLAttDef::Fixed : 01346 fInternalSubset.append(chSpace); 01347 fInternalSubset.append(XMLUni::fgFixedString); 01348 break; 01349 default: 01350 // remaining types don't belong to a DTD 01351 break; 01352 } 01353 01354 const XMLCh* defaultValue = attDef.getValue(); 01355 if (defaultValue != 0) { 01356 fInternalSubset.append(chSpace); 01357 fInternalSubset.append(chDoubleQuote); 01358 fInternalSubset.append(defaultValue); 01359 fInternalSubset.append(chDoubleQuote); 01360 } 01361 } 01362 } 01363 } 01364 01365 void AbstractDOMParser::doctypeComment 01366 ( 01367 const XMLCh* const comment 01368 ) 01369 { 01370 if (fDocumentType->isIntSubsetReading()) 01371 { 01372 if (comment != 0) 01373 { 01374 fInternalSubset.append(XMLUni::fgCommentString); 01375 fInternalSubset.append(chSpace); 01376 fInternalSubset.append(comment); 01377 fInternalSubset.append(chSpace); 01378 fInternalSubset.append(chDash); 01379 fInternalSubset.append(chDash); 01380 fInternalSubset.append(chCloseAngle); 01381 } 01382 } 01383 } 01384 01385 void AbstractDOMParser::doctypeDecl 01386 ( 01387 const DTDElementDecl& elemDecl 01388 , const XMLCh* const publicId 01389 , const XMLCh* const systemId 01390 , const bool 01391 , const bool 01392 ) 01393 { 01394 fDocumentType = (DOMDocumentTypeImpl *) fDocument->createDocumentType(elemDecl.getFullName(), publicId, systemId); 01395 fDocument->setDocumentType(fDocumentType); 01396 01397 } 01398 01399 void AbstractDOMParser::doctypePI 01400 ( 01401 const XMLCh* const target 01402 , const XMLCh* const data 01403 ) 01404 { 01405 if (fDocumentType->isIntSubsetReading()) 01406 { 01407 //add these chars to internalSubset variable 01408 fInternalSubset.append(chOpenAngle); 01409 fInternalSubset.append(chQuestion); 01410 fInternalSubset.append(target); 01411 fInternalSubset.append(chSpace); 01412 fInternalSubset.append(data); 01413 fInternalSubset.append(chQuestion); 01414 fInternalSubset.append(chCloseAngle); 01415 } 01416 } 01417 01418 01419 void AbstractDOMParser::doctypeWhitespace 01420 ( 01421 const XMLCh* const chars 01422 , const XMLSize_t length 01423 ) 01424 { 01425 if (fDocumentType->isIntSubsetReading()) 01426 fInternalSubset.append(chars, length); 01427 } 01428 01429 void AbstractDOMParser::elementDecl 01430 ( 01431 const DTDElementDecl& decl 01432 , const bool 01433 ) 01434 { 01435 if (fDocumentType->isIntSubsetReading()) 01436 { 01437 fInternalSubset.append(chOpenAngle); 01438 fInternalSubset.append(chBang); 01439 fInternalSubset.append(XMLUni::fgElemString); 01440 fInternalSubset.append(chSpace); 01441 fInternalSubset.append(decl.getFullName()); 01442 01443 //get the ContentSpec information 01444 const XMLCh* contentModel = decl.getFormattedContentModel(); 01445 if (contentModel != 0) { 01446 fInternalSubset.append(chSpace); 01447 fInternalSubset.append(contentModel); 01448 } 01449 01450 fInternalSubset.append(chCloseAngle); 01451 } 01452 } 01453 01454 void AbstractDOMParser::endAttList 01455 ( 01456 const DTDElementDecl& elemDecl 01457 ) 01458 { 01459 if (fDocumentType->isIntSubsetReading()) 01460 { 01461 //print the closing angle 01462 fInternalSubset.append(chCloseAngle); 01463 } 01464 01465 // this section sets up default attributes. 01466 // default attribute nodes are stored in a NamedNodeMap DocumentTypeImpl::elements 01467 // default attribute data attached to the document is used to conform to the 01468 // DOM spec regarding creating element nodes & removing attributes with default values 01469 // see DocumentTypeImpl 01470 if (elemDecl.hasAttDefs()) 01471 { 01472 XMLAttDefList* defAttrs = &elemDecl.getAttDefList(); 01473 XMLAttDef* attr = 0; 01474 01475 DOMAttrImpl * insertAttr = 0; 01476 DOMElement *elem = fDocument->createElement(elemDecl.getFullName()); 01477 DOMElementImpl *elemImpl = (DOMElementImpl *) elem; 01478 bool doNamespaces = fScanner->getDoNamespaces(); 01479 01480 for(XMLSize_t i=0; i<defAttrs->getAttDefCount(); i++) 01481 { 01482 attr = &defAttrs->getAttDef(i); 01483 if (attr->getValue() != 0) 01484 { 01485 if (doNamespaces) 01486 { 01487 // DOM Level 2 wants all namespace declaration attributes 01488 // to be bound to "http://www.w3.org/2000/xmlns/" 01489 // So as long as the XML parser doesn't do it, it needs to 01490 // done here. 01491 const XMLCh* qualifiedName = attr->getFullName(); 01492 int index = DOMDocumentImpl::indexofQualifiedName(qualifiedName); 01493 01494 XMLBufBid bbQName(&fBufMgr); 01495 XMLBuffer& buf = bbQName.getBuffer(); 01496 static const XMLCh XMLNS[] = { 01497 chLatin_x, chLatin_m, chLatin_l, chLatin_n, chLatin_s, chNull}; 01498 01499 if (index > 0) { 01500 // there is prefix 01501 // map to XML URI for all cases except when prefix == "xmlns" 01502 XMLCh* prefix; 01503 XMLCh temp[1000]; 01504 01505 if (index > 999) 01506 prefix = (XMLCh*) fMemoryManager->allocate 01507 ( 01508 (index + 1) * sizeof(XMLCh) 01509 );//new XMLCh[index+1]; 01510 else 01511 prefix = temp; 01512 01513 XMLString::subString(prefix ,qualifiedName, 0, index, fMemoryManager); 01514 01515 if (XMLString::equals(prefix,XMLNS)) 01516 buf.append(XMLUni::fgXMLNSURIName); 01517 else 01518 buf.append(XMLUni::fgXMLURIName); 01519 01520 if (index > 999) 01521 fMemoryManager->deallocate(prefix);//delete [] prefix; 01522 } 01523 else { 01524 // No prefix 01525 if (XMLString::equals(qualifiedName,XMLNS)) 01526 buf.append(XMLUni::fgXMLNSURIName); 01527 } 01528 01529 insertAttr = (DOMAttrImpl *) fDocument->createAttributeNS( 01530 buf.getRawBuffer(), // NameSpaceURI 01531 qualifiedName); // qualified name 01532 01533 DOMNode* remAttr = elemImpl->setAttributeNodeNS(insertAttr); 01534 if (remAttr) 01535 remAttr->release(); 01536 } 01537 else 01538 { 01539 // Namespaces is turned off... 01540 insertAttr = (DOMAttrImpl *) fDocument->createAttribute(attr->getFullName()); 01541 DOMNode* remAttr = elemImpl->setAttributeNode(insertAttr); 01542 if (remAttr) 01543 remAttr->release(); 01544 } 01545 01546 insertAttr->setValueFast(attr->getValue()); 01547 insertAttr->setSpecified(false); 01548 } 01549 } 01550 DOMNode* rem = fDocumentType->getElements()->setNamedItem(elemImpl); 01551 if (rem) 01552 rem->release(); 01553 } 01554 } 01555 01556 void AbstractDOMParser::endIntSubset() 01557 { 01558 fDocumentType->setInternalSubset(fInternalSubset.getRawBuffer()); 01559 // the buffer shouldn't be released as it is reused in the next parse 01560 // fBufMgr.releaseBuffer(fInternalSubset); 01561 fDocumentType->fIntSubsetReading = false; 01562 } 01563 01564 void AbstractDOMParser::endExtSubset() 01565 { 01566 } 01567 01568 void AbstractDOMParser::entityDecl 01569 ( 01570 const DTDEntityDecl& entityDecl 01571 , const bool 01572 , const bool 01573 ) 01574 { 01575 DOMEntityImpl* entity = (DOMEntityImpl *) fDocument->createEntity(entityDecl.getName()); 01576 01577 entity->setPublicId(entityDecl.getPublicId()); 01578 entity->setSystemId(entityDecl.getSystemId()); 01579 entity->setNotationName(entityDecl.getNotationName()); 01580 entity->setBaseURI(entityDecl.getBaseURI()); 01581 01582 DOMEntityImpl *previousDef = (DOMEntityImpl *) 01583 fDocumentType->getEntities()->setNamedItem( entity ); 01584 01585 if (previousDef) 01586 previousDef->release(); 01587 01588 if (fDocumentType->isIntSubsetReading()) 01589 { 01590 //add thes chars to internalSubset variable 01591 fInternalSubset.append(chOpenAngle); 01592 fInternalSubset.append(chBang); 01593 fInternalSubset.append(XMLUni::fgEntityString); 01594 fInternalSubset.append(chSpace); 01595 01596 fInternalSubset.append(entityDecl.getName()); 01597 01598 const XMLCh* id = entity->getPublicId(); 01599 if (id != 0) { 01600 fInternalSubset.append(chSpace); 01601 fInternalSubset.append(XMLUni::fgPubIDString); 01602 fInternalSubset.append(chSpace); 01603 fInternalSubset.append(chDoubleQuote); 01604 fInternalSubset.append(id); 01605 fInternalSubset.append(chDoubleQuote); 01606 } 01607 id = entity->getSystemId(); 01608 if (id != 0) { 01609 fInternalSubset.append(chSpace); 01610 fInternalSubset.append(XMLUni::fgSysIDString); 01611 fInternalSubset.append(chSpace); 01612 fInternalSubset.append(chDoubleQuote); 01613 fInternalSubset.append(id); 01614 fInternalSubset.append(chDoubleQuote); 01615 01616 } 01617 id = entity->getNotationName(); 01618 if (id != 0) { 01619 fInternalSubset.append(chSpace); 01620 fInternalSubset.append(XMLUni::fgNDATAString); 01621 fInternalSubset.append(chSpace); 01622 fInternalSubset.append(id); 01623 } 01624 id = entityDecl.getValue(); 01625 if (id !=0) { 01626 fInternalSubset.append(chSpace); 01627 fInternalSubset.append(chDoubleQuote); 01628 fInternalSubset.append(id); 01629 fInternalSubset.append(chDoubleQuote); 01630 } 01631 01632 fInternalSubset.append(chCloseAngle); 01633 } 01634 01635 } 01636 01637 void AbstractDOMParser::resetDocType() 01638 { 01639 fDocumentType = 0; 01640 } 01641 01642 void AbstractDOMParser::notationDecl 01643 ( 01644 const XMLNotationDecl& notDecl 01645 , const bool 01646 ) 01647 { 01648 DOMNotationImpl* notation = (DOMNotationImpl *)fDocument->createNotation(notDecl.getName()); 01649 notation->setPublicId(notDecl.getPublicId()); 01650 notation->setSystemId(notDecl.getSystemId()); 01651 notation->setBaseURI(notDecl.getBaseURI()); 01652 01653 DOMNode* rem = fDocumentType->getNotations()->setNamedItem( notation ); 01654 if (rem) 01655 rem->release(); 01656 01657 if (fDocumentType->isIntSubsetReading()) 01658 { 01659 //add thes chars to internalSubset variable 01660 fInternalSubset.append(chOpenAngle); 01661 fInternalSubset.append(chBang); 01662 fInternalSubset.append(XMLUni::fgNotationString); 01663 fInternalSubset.append(chSpace); 01664 01665 fInternalSubset.append(notDecl.getName()); 01666 01667 const XMLCh* id = notation->getPublicId(); 01668 if (id != 0) { 01669 fInternalSubset.append(chSpace); 01670 fInternalSubset.append(XMLUni::fgPubIDString); 01671 fInternalSubset.append(chSpace); 01672 fInternalSubset.append(chDoubleQuote); 01673 fInternalSubset.append(id); 01674 fInternalSubset.append(chDoubleQuote); 01675 } 01676 id = notation->getSystemId(); 01677 if (id != 0) { 01678 fInternalSubset.append(chSpace); 01679 fInternalSubset.append(XMLUni::fgSysIDString); 01680 fInternalSubset.append(chSpace); 01681 fInternalSubset.append(chDoubleQuote); 01682 fInternalSubset.append(id); 01683 fInternalSubset.append(chDoubleQuote); 01684 01685 } 01686 fInternalSubset.append(chCloseAngle); 01687 } 01688 } 01689 01690 void AbstractDOMParser::startAttList 01691 ( 01692 const DTDElementDecl& elemDecl 01693 ) 01694 { 01695 if (fDocumentType->isIntSubsetReading()) 01696 { 01697 fInternalSubset.append(chOpenAngle); 01698 fInternalSubset.append(chBang); 01699 fInternalSubset.append(XMLUni::fgAttListString); 01700 fInternalSubset.append(chSpace); 01701 fInternalSubset.append(elemDecl.getFullName()); 01702 } 01703 } 01704 01705 void AbstractDOMParser::startIntSubset() 01706 { 01707 fDocumentType->fIntSubsetReading = true; 01708 } 01709 01710 void AbstractDOMParser::startExtSubset() 01711 { 01712 } 01713 01714 void AbstractDOMParser::TextDecl 01715 ( 01716 const XMLCh* const versionStr 01717 , const XMLCh* const encodingStr 01718 ) 01719 { 01720 if (fCurrentEntity) { 01721 fCurrentEntity->setXmlVersion(versionStr); 01722 fCurrentEntity->setXmlEncoding(encodingStr); 01723 } 01724 } 01725 01726 DOMCDATASection* AbstractDOMParser:: 01727 createCDATASection (const XMLCh* s, XMLSize_t n) 01728 { 01729 return new (fDocument, DOMMemoryManager::CDATA_SECTION_OBJECT) 01730 DOMCDATASectionImpl(fDocument, s, n); 01731 } 01732 01733 01734 DOMText* AbstractDOMParser:: 01735 createText (const XMLCh* s, XMLSize_t n) 01736 { 01737 return new (fDocument, DOMMemoryManager::TEXT_OBJECT) 01738 DOMTextImpl(fDocument, s, n); 01739 } 01740 01741 01742 DOMElement* AbstractDOMParser:: 01743 createElement (const XMLCh* name) 01744 { 01745 return new (fDocument, DOMMemoryManager::ELEMENT_OBJECT) 01746 DOMElementImpl(fDocument, name); 01747 } 01748 01749 DOMElement* AbstractDOMParser:: 01750 createElementNS (const XMLCh* namespaceURI, 01751 const XMLCh* elemPrefix, 01752 const XMLCh* localName, 01753 const XMLCh* qName) 01754 { 01755 return new (fDocument, DOMMemoryManager::ELEMENT_NS_OBJECT) 01756 DOMElementNSImpl (fDocument, 01757 namespaceURI, 01758 elemPrefix, 01759 localName, 01760 qName); 01761 } 01762 01763 DOMAttr* AbstractDOMParser:: 01764 createAttr (const XMLCh* name) 01765 { 01766 return new (fDocument, DOMMemoryManager::ATTR_OBJECT) 01767 DOMAttrImpl(fDocument, name); 01768 } 01769 01770 DOMAttr* AbstractDOMParser:: 01771 createAttrNS (const XMLCh* namespaceURI, 01772 const XMLCh* elemPrefix, 01773 const XMLCh* localName, 01774 const XMLCh* qName) 01775 { 01776 return new (fDocument, DOMMemoryManager::ATTR_NS_OBJECT) 01777 DOMAttrNSImpl (fDocument, 01778 namespaceURI, 01779 elemPrefix, 01780 localName, 01781 qName); 01782 } 01783 01784 XERCES_CPP_NAMESPACE_END