domdocumentimpl.cpp
来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 1,362 行 · 第 1/3 页
CPP
1,362 行
/* * Copyright 2001-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: DOMDocumentImpl.cpp,v 1.58 2004/09/08 13:55:51 peiyongz Exp $ */#include "DOMDocumentImpl.hpp"#include "DOMCasts.hpp"#include "DOMConfigurationImpl.hpp"#include "DOMDocumentTypeImpl.hpp"#include "DOMAttrImpl.hpp"#include "DOMAttrNSImpl.hpp"#include "DOMCDATASectionImpl.hpp"#include "DOMCommentImpl.hpp"#include "DOMDeepNodeListImpl.hpp"#include "DOMDocumentFragmentImpl.hpp"#include "DOMElementImpl.hpp"#include "XSDElementNSImpl.hpp"#include "DOMEntityImpl.hpp"#include "DOMEntityReferenceImpl.hpp"#include "DOMNormalizer.hpp"#include "DOMNotationImpl.hpp"#include "DOMProcessingInstructionImpl.hpp"#include "DOMTextImpl.hpp"#include "DOMStringPool.hpp"#include "DOMTreeWalkerImpl.hpp"#include "DOMNodeIteratorImpl.hpp"#include "DOMNodeIDMap.hpp"#include "DOMRangeImpl.hpp"#include <xercesc/dom/DOMImplementation.hpp>#include <xercesc/util/XMLChar.hpp>#include <xercesc/framework/MemoryManager.hpp>#include <xercesc/util/OutOfMemoryException.hpp>XERCES_CPP_NAMESPACE_BEGIN//// Constructors. Warning - be very careful with the ordering of initialization// of the heap. Ordering depends on the order of declaration// in the .hpp file, not on the order of initializers here// in the constructor. The heap declaration can not be// first - fNode and fParent must be first for the casting// functions in DOMCasts to work correctly. This means that// fNode and fParent constructors used here can not// allocate.//DOMDocumentImpl::DOMDocumentImpl(MemoryManager* const manager) : fNode(this), fParent(this), fNodeIDMap(0), fActualEncoding(0), fEncoding(0), fStandalone(false), fVersion(0), fDocumentURI(0), fDOMConfiguration(0), fUserDataTableKeys(17, manager), fUserDataTable(0), fCurrentBlock(0), fFreePtr(0), fFreeBytesRemaining(0), fRecycleNodePtr(0), fRecycleBufferPtr(0), fNodeListPool(0), fDocType(0), fDocElement(0), fNamePool(0), fNormalizer(0), fRanges(0), fNodeIterators(0), fMemoryManager(manager), fChanges(0), errorChecking(true){ fNamePool = new (this) DOMStringPool(257, this);}//DOM Level 2DOMDocumentImpl::DOMDocumentImpl(const XMLCh *fNamespaceURI, const XMLCh *qualifiedName, DOMDocumentType *doctype, MemoryManager* const manager) : fNode(this), fParent(this), fNodeIDMap(0), fActualEncoding(0), fEncoding(0), fStandalone(false), fVersion(0), fDocumentURI(0), fDOMConfiguration(0), fUserDataTableKeys(17, manager), fUserDataTable(0), fCurrentBlock(0), fFreePtr(0), fFreeBytesRemaining(0), fRecycleNodePtr(0), fRecycleBufferPtr(0), fNodeListPool(0), fDocType(0), fDocElement(0), fNamePool(0), fNormalizer(0), fRanges(0), fNodeIterators(0), fMemoryManager(manager), fChanges(0), errorChecking(true){ fNamePool = new (this) DOMStringPool(257, this); try { setDocumentType(doctype); if (qualifiedName) appendChild(createElementNS(fNamespaceURI, qualifiedName)); //root element else if (fNamespaceURI) throw DOMException(DOMException::NAMESPACE_ERR, 0, getMemoryManager()); } catch(const OutOfMemoryException&) { throw; } catch (...) { this->deleteHeap(); throw; }}void DOMDocumentImpl::setDocumentType(DOMDocumentType *doctype){ if (!doctype) return; // New doctypes can be created either with the factory methods on DOMImplementation, in // which case ownerDocument will be 0, or with methods on DocumentImpl, in which case // ownerDocument will be set, but the DocType won't yet be a child of the document. if (doctype->getOwnerDocument() != 0 && doctype->getOwnerDocument() != this) throw DOMException( //one doctype can belong to only one DOMDocumentImpl DOMException::WRONG_DOCUMENT_ERR, 0, getMemoryManager()); DOMDocumentTypeImpl* doctypeImpl = (DOMDocumentTypeImpl*) doctype; doctypeImpl->setOwnerDocument(this); // The doctype can not have any Entities or Notations yet, because they can not // be created except through factory methods on a document. // revisit. What if this doctype is already a child of the document? appendChild(doctype);}DOMDocumentImpl::~DOMDocumentImpl(){ // Clean up the fNodeListPool if (fNodeListPool) fNodeListPool->cleanup(); if (fRanges) delete fRanges; //fRanges->cleanup(); if (fNodeIterators) delete fNodeIterators;//fNodeIterators->cleanup(); if (fUserDataTable) delete fUserDataTable;//fUserDataTable->cleanup(); if (fRecycleNodePtr) { fRecycleNodePtr->deleteAllElements(); delete fRecycleNodePtr; } if (fRecycleBufferPtr) { delete fRecycleBufferPtr; } delete fNormalizer; // Delete the heap for this document. This uncerimoniously yanks the storage // out from under all of the nodes in the document. Destructors are NOT called. this->deleteHeap();}DOMNode *DOMDocumentImpl::cloneNode(bool deep) const { // Note: the cloned document node goes on the same heap we live in. DOMDocumentImpl *newdoc = new (fMemoryManager) DOMDocumentImpl(fMemoryManager); if(fEncoding && *fEncoding) newdoc->setEncoding(fEncoding); if(fVersion && *fVersion) newdoc->setVersion(fVersion); newdoc->setStandalone(fStandalone); // then the children by _importing_ them if (deep) for (DOMNode *n = this->getFirstChild(); n != 0; n = n->getNextSibling()) { newdoc->appendChild(newdoc->importNode(n, true, true)); } fNode.callUserDataHandlers(DOMUserDataHandler::NODE_CLONED, this, newdoc); return newdoc;}const XMLCh * DOMDocumentImpl::getNodeName() const { static const XMLCh nam[] = // "#document" {chPound, chLatin_d, chLatin_o, chLatin_c, chLatin_u, chLatin_m, chLatin_e, chLatin_n, chLatin_t, 0}; return nam;}short DOMDocumentImpl::getNodeType() const { return DOMNode::DOCUMENT_NODE;}// even though ownerDocument refers to this in this implementation// the DOM Level 2 spec says it must be 0, so make it appear soDOMDocument * DOMDocumentImpl::getOwnerDocument() const { return 0;}DOMAttr *DOMDocumentImpl::createAttribute(const XMLCh *nam){ if(!nam || !isXMLName(nam)) throw DOMException(DOMException::INVALID_CHARACTER_ERR,0, getMemoryManager()); return new (this, DOMDocumentImpl::ATTR_OBJECT) DOMAttrImpl(this,nam);}DOMCDATASection *DOMDocumentImpl::createCDATASection(const XMLCh *data) { return new (this, DOMDocumentImpl::CDATA_SECTION_OBJECT) DOMCDATASectionImpl(this,data);}DOMComment *DOMDocumentImpl::createComment(const XMLCh *data){ return new (this, DOMDocumentImpl::COMMENT_OBJECT) DOMCommentImpl(this, data);}DOMDocumentFragment *DOMDocumentImpl::createDocumentFragment(){ return new (this, DOMDocumentImpl::DOCUMENT_FRAGMENT_OBJECT) DOMDocumentFragmentImpl(this);}DOMDocumentType *DOMDocumentImpl::createDocumentType(const XMLCh *nam){ if (!nam || !isXMLName(nam)) throw DOMException( DOMException::INVALID_CHARACTER_ERR, 0, getMemoryManager()); return new (this, DOMDocumentImpl::DOCUMENT_TYPE_OBJECT) DOMDocumentTypeImpl(this, nam, false);}DOMDocumentType * DOMDocumentImpl::createDocumentType(const XMLCh *qualifiedName, const XMLCh *publicId, const XMLCh *systemId){ if (!qualifiedName || !isXMLName(qualifiedName)) throw DOMException( DOMException::INVALID_CHARACTER_ERR, 0, getMemoryManager()); return new (this, DOMDocumentImpl::DOCUMENT_TYPE_OBJECT) DOMDocumentTypeImpl(this, qualifiedName, publicId, systemId, false);}DOMElement *DOMDocumentImpl::createElement(const XMLCh *tagName){ if(!tagName || !isXMLName(tagName)) throw DOMException(DOMException::INVALID_CHARACTER_ERR,0, getMemoryManager()); return new (this, DOMDocumentImpl::ELEMENT_OBJECT) DOMElementImpl(this,tagName);}DOMElement *DOMDocumentImpl::createElementNoCheck(const XMLCh *tagName){ return new (this, DOMDocumentImpl::ELEMENT_OBJECT) DOMElementImpl(this, tagName);}DOMEntity *DOMDocumentImpl::createEntity(const XMLCh *nam){ if (!nam || !isXMLName(nam)) throw DOMException( DOMException::INVALID_CHARACTER_ERR, 0, getMemoryManager()); return new (this, DOMDocumentImpl::ENTITY_OBJECT) DOMEntityImpl(this, nam);}DOMEntityReference *DOMDocumentImpl::createEntityReference(const XMLCh *nam){ if (!nam || !isXMLName(nam)) throw DOMException( DOMException::INVALID_CHARACTER_ERR, 0, getMemoryManager()); return new (this, DOMDocumentImpl::ENTITY_REFERENCE_OBJECT) DOMEntityReferenceImpl(this, nam);}DOMEntityReference *DOMDocumentImpl::createEntityReferenceByParser(const XMLCh *nam){ if (!nam || !isXMLName(nam)) throw DOMException( DOMException::INVALID_CHARACTER_ERR, 0, getMemoryManager()); return new (this, DOMDocumentImpl::ENTITY_REFERENCE_OBJECT) DOMEntityReferenceImpl(this, nam, false);}DOMNotation *DOMDocumentImpl::createNotation(const XMLCh *nam){ if (!nam || !isXMLName(nam)) throw DOMException( DOMException::INVALID_CHARACTER_ERR, 0, getMemoryManager()); return new (this, DOMDocumentImpl::NOTATION_OBJECT) DOMNotationImpl(this, nam);}DOMProcessingInstruction *DOMDocumentImpl::createProcessingInstruction( const XMLCh *target, const XMLCh *data){ if(!target || !isXMLName(target)) throw DOMException(DOMException::INVALID_CHARACTER_ERR,0, getMemoryManager()); return new (this, DOMDocumentImpl::PROCESSING_INSTRUCTION_OBJECT) DOMProcessingInstructionImpl(this,target,data);}DOMText *DOMDocumentImpl::createTextNode(const XMLCh *data){ return new (this, DOMDocumentImpl::TEXT_OBJECT) DOMTextImpl(this,data);}DOMNodeIterator* DOMDocumentImpl::createNodeIterator ( DOMNode *root, unsigned long whatToShow, DOMNodeFilter* filter, bool entityReferenceExpansion){ if (!root) { throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, getMemoryManager()); return 0; } DOMNodeIteratorImpl* nodeIterator = new (this) DOMNodeIteratorImpl(this, root, whatToShow, filter, entityReferenceExpansion); if (fNodeIterators == 0L) { //fNodeIterators = new (this) NodeIterators(1, false); fNodeIterators = new (fMemoryManager) NodeIterators(1, false, fMemoryManager); } fNodeIterators->addElement(nodeIterator); return nodeIterator;}NodeIterators* DOMDocumentImpl::getNodeIterators() const{ return fNodeIterators;}void DOMDocumentImpl::removeNodeIterator(DOMNodeIteratorImpl* nodeIterator){ if (fNodeIterators != 0) { XMLSize_t sz = fNodeIterators->size(); if (sz !=0) { for (XMLSize_t i =0; i<sz; i++) { if (fNodeIterators->elementAt(i) == nodeIterator) { fNodeIterators->removeElementAt(i); break; } } } }}const DOMXPathExpression* DOMDocumentImpl::createExpression(const XMLCh *, const DOMXPathNSResolver *){ throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, getMemoryManager()); return 0;}const DOMXPathNSResolver* DOMDocumentImpl::createNSResolver(DOMNode *){ throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, getMemoryManager()); return 0;}void* DOMDocumentImpl::evaluate(const XMLCh *, DOMNode *, const DOMXPathNSResolver *, unsigned short, void* ) { throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, getMemoryManager()); return 0;}DOMTreeWalker* DOMDocumentImpl::createTreeWalker (DOMNode *root, unsigned long whatToShow, DOMNodeFilter* filter, bool entityReferenceExpansion){ if (!root) { throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, getMemoryManager()); return 0; } return new (this) DOMTreeWalkerImpl(root, whatToShow, filter, entityReferenceExpansion);}DOMDocumentType *DOMDocumentImpl::getDoctype() const{ return fDocType;}DOMElement *DOMDocumentImpl::getDocumentElement() const{ return fDocElement;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?