domdocumentimpl.cpp
来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 1,362 行 · 第 1/3 页
CPP
1,362 行
return retList;}//Introduced in DOM Level 3const XMLCh* DOMDocumentImpl::getActualEncoding() const { return fActualEncoding;}void DOMDocumentImpl::setActualEncoding(const XMLCh* actualEncoding){ fActualEncoding = cloneString(actualEncoding);}const XMLCh* DOMDocumentImpl::getEncoding() const { return fEncoding;}void DOMDocumentImpl::setEncoding(const XMLCh* encoding){ fEncoding = cloneString(encoding);}bool DOMDocumentImpl::getStandalone() const{ return fStandalone;}void DOMDocumentImpl::setStandalone(bool standalone){ fStandalone = standalone;}const XMLCh* DOMDocumentImpl::getVersion() const { return fVersion;}void DOMDocumentImpl::setVersion(const XMLCh* version){ if ((version && *version) && !XMLString::equals(version, XMLUni::fgVersion1_0) && !XMLString::equals(version, XMLUni::fgVersion1_1)) throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, getMemoryManager()); fVersion = cloneString(version);}const XMLCh* DOMDocumentImpl::getDocumentURI() const{ return fDocumentURI;}void DOMDocumentImpl::setDocumentURI(const XMLCh* documentURI){ if (documentURI && *documentURI) { XMLCh* temp = (XMLCh*) this->allocate((XMLString::stringLen(documentURI) + 9)*sizeof(XMLCh)); XMLString::fixURI(documentURI, temp); fDocumentURI = temp; } else fDocumentURI = 0;}bool DOMDocumentImpl::getStrictErrorChecking() const { return getErrorChecking();}void DOMDocumentImpl::setStrictErrorChecking(bool strictErrorChecking) { setErrorChecking(strictErrorChecking);}DOMNode* DOMDocumentImpl::adoptNode(DOMNode*) { throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, getMemoryManager()); return 0;}void DOMDocumentImpl::normalizeDocument() { if(!fNormalizer) fNormalizer = new (fMemoryManager) DOMNormalizer(fMemoryManager); fNormalizer->normalizeDocument(this);}DOMConfiguration* DOMDocumentImpl::getDOMConfiguration() const { if(!fDOMConfiguration) ((DOMDocumentImpl*)this)->fDOMConfiguration = new ((DOMDocumentImpl*)this) DOMConfigurationImpl(fMemoryManager); return fDOMConfiguration;}void DOMDocumentImpl::setDOMConfiguration(DOMConfiguration *config) { fDOMConfiguration = config;}DOMNode *DOMDocumentImpl::importNode(DOMNode *source, bool deep, bool cloningDoc){ DOMNode *newnode=0; bool oldErrorCheckingFlag = errorChecking; switch (source->getNodeType()) { case DOMNode::ELEMENT_NODE : { DOMElement *newelement; if (source->getLocalName() == 0) newelement = createElement(source->getNodeName()); else newelement = createElementNS(source->getNamespaceURI(), source->getNodeName()); DOMNamedNodeMap *srcattr=source->getAttributes(); if(srcattr!=0) for(XMLSize_t i=0;i<srcattr->getLength();++i) { DOMAttr *attr = (DOMAttr *) srcattr->item(i); if (attr -> getSpecified()) { // not a default attribute DOMAttr *nattr = (DOMAttr *) importNode(attr, true, false); if (attr -> getLocalName() == 0) newelement->setAttributeNode(nattr); else newelement->setAttributeNodeNS(nattr); // if the imported attribute is of ID type, register the new node in fNodeIDMap if (attr->isId()) { castToNodeImpl(nattr)->isIdAttr(true); if (!fNodeIDMap) fNodeIDMap = new (this) DOMNodeIDMap(500, this); fNodeIDMap->add((DOMAttr*)nattr); } } } newnode=newelement; } break; case DOMNode::ATTRIBUTE_NODE : if (source->getLocalName() == 0) newnode = createAttribute(source->getNodeName()); else newnode = createAttributeNS(source->getNamespaceURI(), source->getNodeName()); deep = true; // Kids carry value break; case DOMNode::TEXT_NODE : newnode = createTextNode(source->getNodeValue()); break; case DOMNode::CDATA_SECTION_NODE : newnode = createCDATASection(source->getNodeValue()); break; case DOMNode::ENTITY_REFERENCE_NODE : { DOMEntityReferenceImpl* newentityRef = (DOMEntityReferenceImpl*)createEntityReference(source->getNodeName()); newnode=newentityRef; errorChecking = false; newentityRef->setReadOnly(false, true); //allow deep import temporarily } break; case DOMNode::ENTITY_NODE : { DOMEntity *srcentity=(DOMEntity *)source; DOMEntityImpl *newentity = (DOMEntityImpl *)createEntity(source->getNodeName()); newentity->setPublicId(srcentity->getPublicId()); newentity->setSystemId(srcentity->getSystemId()); newentity->setNotationName(srcentity->getNotationName()); // Kids carry additional value newnode=newentity; castToNodeImpl(newentity)->setReadOnly(false, true);// allow deep import temporarily } break; case DOMNode::PROCESSING_INSTRUCTION_NODE : newnode = createProcessingInstruction(source->getNodeName(), source->getNodeValue()); break; case DOMNode::COMMENT_NODE : newnode = createComment(source->getNodeValue()); break; case DOMNode::DOCUMENT_TYPE_NODE : { // unless this is used as part of cloning a Document // forbid it for the sake of being compliant to the DOM spec if (!cloningDoc) throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, getMemoryManager()); DOMDocumentType *srcdoctype = (DOMDocumentType *)source; DOMDocumentType *newdoctype = (DOMDocumentType *) createDocumentType(srcdoctype->getNodeName(), srcdoctype->getPublicId(), srcdoctype->getSystemId()); // Values are on NamedNodeMaps DOMNamedNodeMap *smap = srcdoctype->getEntities(); DOMNamedNodeMap *tmap = newdoctype->getEntities(); if(smap != 0) { for(XMLSize_t i = 0; i < smap->getLength(); i++) { tmap->setNamedItem(importNode(smap->item(i), true, false)); } } smap = srcdoctype->getNotations(); tmap = newdoctype->getNotations(); if (smap != 0) { for(XMLSize_t i = 0; i < smap->getLength(); i++) { tmap->setNamedItem(importNode(smap->item(i), true, false)); } } const XMLCh* intSubset=srcdoctype->getInternalSubset(); if(intSubset != 0) { ((DOMDocumentTypeImpl *)newdoctype)->setInternalSubset(intSubset); } // NOTE: At this time, the DOM definition of DocumentType // doesn't cover Elements and their Attributes. domimpl's // extentions in that area will not be preserved, even if // copying from domimpl to domimpl. We could special-case // that here. Arguably we should. Consider. ????? newnode = newdoctype; } break; case DOMNode::DOCUMENT_FRAGMENT_NODE : newnode = createDocumentFragment(); // No name, kids carry value break; case DOMNode::NOTATION_NODE : { DOMNotation *srcnotation=(DOMNotation *)source; DOMNotationImpl *newnotation = (DOMNotationImpl *)createNotation(source->getNodeName()); newnotation->setPublicId(srcnotation->getPublicId()); newnotation->setSystemId(srcnotation->getSystemId()); // Kids carry additional value newnode=newnotation; // No name, no value break; } case DOMNode::DOCUMENT_NODE : // Document can't be child of Document default: // Unknown node type throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, getMemoryManager()); } // If deep, replicate and attach the kids. if (deep) for (DOMNode *srckid = source->getFirstChild(); srckid != 0; srckid = srckid->getNextSibling()) { newnode->appendChild(importNode(srckid, true, false)); } if (newnode->getNodeType() == DOMNode::ENTITY_REFERENCE_NODE || newnode->getNodeType() == DOMNode::ENTITY_NODE) { castToNodeImpl(newnode)->setReadOnly(true, true); errorChecking = oldErrorCheckingFlag; } if (!cloningDoc) fNode.callUserDataHandlers(DOMUserDataHandler::NODE_IMPORTED, source, newnode); return newnode;}// user data utilityvoid* DOMDocumentImpl::setUserData(DOMNodeImpl* n, const XMLCh* key, void* data, DOMUserDataHandler* handler){ void* oldData = 0; unsigned int keyId=fUserDataTableKeys.addOrFind(key); if (!fUserDataTable) { // create the table on heap so that it can be cleaned in destructor fUserDataTable = new (fMemoryManager) RefHash2KeysTableOf<DOMUserDataRecord> ( 109 , true , new (fMemoryManager) HashPtr() , fMemoryManager ); } else { DOMUserDataRecord* oldDataRecord = fUserDataTable->get((void*)n, keyId); if (oldDataRecord) { oldData = oldDataRecord->getKey(); fUserDataTable->removeKey((void*)n, keyId); } } if (data) { // clone the key first, and create the DOMUserDataRecord // create on the heap and adopted by the hashtable which will delete it upon removal. fUserDataTable->put((void*)n, keyId, new (fMemoryManager) DOMUserDataRecord(data, handler)); } else { RefHash2KeysTableOfEnumerator<DOMUserDataRecord> enumKeys(fUserDataTable, false, fMemoryManager); enumKeys.setPrimaryKey(n); if (!enumKeys.hasMoreElements()) n->hasUserData(false); } return oldData;}void* DOMDocumentImpl::getUserData(const DOMNodeImpl* n, const XMLCh* key) const{ if (fUserDataTable) { unsigned int keyId=fUserDataTableKeys.getId(key); if(keyId!=0) { DOMUserDataRecord* dataRecord = fUserDataTable->get((void*)n, keyId); if (dataRecord) return dataRecord->getKey(); } } return 0;}void DOMDocumentImpl::callUserDataHandlers(const DOMNodeImpl* n, DOMUserDataHandler::DOMOperationType operation, const DOMNode* src, const DOMNode* dst) const{ if (fUserDataTable) { RefHash2KeysTableOfEnumerator<DOMUserDataRecord> userDataEnum(fUserDataTable, false, fMemoryManager); userDataEnum.setPrimaryKey(n); while (userDataEnum.hasMoreElements()) { // get the key void* key; int key2; userDataEnum.nextElementKey(key,key2); // get the DOMUserDataRecord DOMUserDataRecord* userDataRecord = fUserDataTable->get((void*)n,key2); // get the handler DOMUserDataHandler* handler = userDataRecord->getValue(); if (handler) { // get the data void* data = userDataRecord->getKey(); const XMLCh* userKey = fUserDataTableKeys.getValueForId(key2); handler->handle(operation, userKey, data, src, dst); } // if the operation is deleted, we in fact should remove the data from the table if (operation == DOMUserDataHandler::NODE_DELETED) fUserDataTable->removeKey((void*)n,key2); } }}void DOMDocumentImpl::transferUserData(DOMNodeImpl* n1, DOMNodeImpl* n2){ if (fUserDataTable) { fUserDataTable->transferElement((void*)n1, (void*)n2); n1->hasUserData(false); n2->hasUserData(true); }}DOMNode* DOMDocumentImpl::renameNode(DOMNode* n, const XMLCh* namespaceURI, const XMLCh* name){ if (n->getOwnerDocument() != this) if (n->getNodeType() == DOCUMENT_NODE) throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, getMemoryManager()); else throw DOMException(DOMException::WRONG_DOCUMENT_ERR, 0, getMemoryManager()); switch (n->getNodeType()) { case ELEMENT_NODE: return ((DOMElementImpl*)n)->rename(namespaceURI, name); case ATTRIBUTE_NODE: return ((DOMAttrImpl*)n)->rename(namespaceURI, name); default: throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, getMemoryManager()); } return 0;}void DOMDocumentImpl::release(){ DOMDocument* doc = (DOMDocument*) this; fNode.callUserDataHandlers(DOMUserDataHandler::NODE_DELETED, 0, 0); // notify userdatahandler first, if we have some if (fUserDataTable) releaseDocNotifyUserData(this); // release the docType in case it was created from heap if (fDocType) { castToNodeImpl(fDocType)->isToBeReleased(true); fDocType->release(); } // delete the document memory pool delete doc;}void DOMDocumentImpl::releaseDocNotifyUserData(DOMNode* object){ DOMNode *child = object->getFirstChild(); while( child != 0) { DOMNamedNodeMap *attrlist=child->getAttributes(); if(attrlist!=0) for(XMLSize_t i=0;i<attrlist->getLength();++i) releaseDocNotifyUserData(attrlist->item(i)); releaseDocNotifyUserData(child); child = child->getNextSibling(); } castToNodeImpl(object)->callUserDataHandlers(DOMUserDataHandler::NODE_DELETED, 0, 0);}void DOMDocumentImpl::release(DOMNode* object, NodeObjectType type){ if (!fRecycleNodePtr) fRecycleNodePtr = new (fMemoryManager) RefArrayOf<DOMNodePtr> (15, fMemoryManager); if (!fRecycleNodePtr->operator[](type)) fRecycleNodePtr->operator[](type) = new (fMemoryManager) RefStackOf<DOMNode> (15, false, fMemoryManager); fRecycleNodePtr->operator[](type)->push(object);}void DOMDocumentImpl::releaseBuffer(DOMBuffer* buffer){ if (!fRecycleBufferPtr) fRecycleBufferPtr = new (fMemoryManager) RefStackOf<DOMBuffer> (15, false, fMemoryManager); fRecycleBufferPtr->push(buffer);}DOMBuffer* DOMDocumentImpl::popBuffer(){ if (!fRecycleBufferPtr || fRecycleBufferPtr->empty()) return 0; return fRecycleBufferPtr->pop();}void * DOMDocumentImpl::allocate(size_t amount, NodeObjectType type){ if (!fRecycleNodePtr) return allocate(amount); DOMNodePtr* ptr = fRecycleNodePtr->operator[](type); if (!ptr || ptr->empty()) return allocate(amount); return (void*) ptr->pop();}XERCES_CPP_NAMESPACE_END
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?