documentimpl.cpp
来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 845 行 · 第 1/2 页
CPP
845 行
// referenced(). Override this function here in class DocumentImpl because// we don't want the action taken in NodeImpl, which is// to add a reference to the node's owning document.//void DocumentImpl::referenced(){ // Intentionally empty.};NodeImpl *DocumentImpl::removeChild(NodeImpl *oldChild){ ParentNode::removeChild(oldChild); // If remove succeeded, un-cache the kid appropriately if(oldChild->isElementImpl()) docElement=null; else if(oldChild->isDocumentTypeImpl()) docType=null; return oldChild;};//// unreferenced() will be called whenever the refernce count on// this document goes from 1 to 0. In all cases, when this// happens to a document node (which is the case here), it// is time to actually delete the document.//// See also NodeImpl::referenced() and unreferenced(), which// update document node ref counts based on references coming// or going to nodes owned by the document.//void DocumentImpl::unreferenced(){ deleteIf(this);};//Introduced in DOM Level 2NodeImpl *DocumentImpl::importNode(NodeImpl *source, bool deep){ NodeImpl *newnode=null; bool oldErrorCheckingFlag = errorChecking; switch (source->getNodeType()) { case DOM_Node::ELEMENT_NODE : { ElementImpl *newelement; if (source->getLocalName() == null) newelement = createElement(source->getNodeName()); else newelement = createElementNS(source->getNamespaceURI(), source->getNodeName()); NamedNodeMapImpl *srcattr=source->getAttributes(); if (srcattr!=null) for(unsigned int i=0;i<srcattr->getLength();++i) { AttrImpl *attr = (AttrImpl *) srcattr->item(i); AttrImpl * pOldAttr = null; if (attr -> getSpecified()) { // not a default attribute AttrImpl *nattr = (AttrImpl *) importNode(attr, true); if (attr -> getLocalName() == null) pOldAttr = newelement->setAttributeNode(nattr); else pOldAttr = newelement->setAttributeNodeNS(nattr); if (pOldAttr) { if (pOldAttr->nodeRefCount == 0) NodeImpl::deleteIf(pOldAttr); } } } newnode=newelement; } break; case DOM_Node::ATTRIBUTE_NODE : { if (source->getLocalName() == null) newnode = createAttribute(source->getNodeName()); else newnode = createAttributeNS(source->getNamespaceURI(), source->getNodeName()); // if source is an AttrImpl from this very same implementation // avoid creating the child nodes if possible// if (source instanceof AttrImpl) { AttrImpl *attr = (AttrImpl *) source; if (attr->hasStringValue()) { AttrImpl *newattr = (AttrImpl *) newnode; newattr->setValue(attr->getValue()); deep = false; } else { deep = true; }// }// else {// // Kids carry value// deep = true;// } } break; case DOM_Node::TEXT_NODE : newnode = createTextNode(source->getNodeValue()); break; case DOM_Node::CDATA_SECTION_NODE : newnode = createCDATASection(source->getNodeValue()); break; case DOM_Node::ENTITY_REFERENCE_NODE : { EntityReferenceImpl* newentityRef = createEntityReference(source->getNodeName()); newnode=newentityRef; errorChecking = false; newentityRef->setReadOnly(false, true); //allow deep import temporarily } break; case DOM_Node::ENTITY_NODE : { EntityImpl *srcentity=(EntityImpl *)source; EntityImpl *newentity = createEntity(source->getNodeName()); newentity->setPublicId(srcentity->getPublicId()); newentity->setSystemId(srcentity->getSystemId()); newentity->setNotationName(srcentity->getNotationName()); // Kids carry additional value newnode=newentity; newentity->setReadOnly(false, true);// allow deep import temporarily } break; case DOM_Node::PROCESSING_INSTRUCTION_NODE : newnode = createProcessingInstruction(source->getNodeName(), source->getNodeValue()); break; case DOM_Node::COMMENT_NODE : newnode = createComment(source->getNodeValue()); break; case DOM_Node::DOCUMENT_TYPE_NODE : { DocumentTypeImpl *srcdoctype = (DocumentTypeImpl *)source; DocumentTypeImpl *newdoctype = (DocumentTypeImpl *) createDocumentType(srcdoctype->getNodeName(), srcdoctype->getPublicId(), srcdoctype->getSystemId()); // Values are on NamedNodeMaps NamedNodeMapImpl *smap = srcdoctype->getEntities(); NamedNodeMapImpl *tmap = newdoctype->getEntities(); if(smap != null) { for(unsigned int i = 0; i < smap->getLength(); i++) { tmap->setNamedItem(importNode(smap->item(i), true)); } } smap = srcdoctype->getNotations(); tmap = newdoctype->getNotations(); if (smap != null) { for(unsigned int i = 0; i < smap->getLength(); i++) { tmap->setNamedItem(importNode(smap->item(i), true)); } } // 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 DOM_Node::DOCUMENT_FRAGMENT_NODE : newnode = createDocumentFragment(); // No name, kids carry value break; case DOM_Node::NOTATION_NODE : { NotationImpl *srcnotation=(NotationImpl *)source; NotationImpl *newnotation = createNotation(source->getNodeName()); newnotation->setPublicId(srcnotation->getPublicId()); newnotation->setSystemId(srcnotation->getSystemId()); // Kids carry additional value newnode=newnotation; // No name, no value break; } case DOM_Node::DOCUMENT_NODE : // Document can't be child of Document default: // Unknown node type throw DOM_DOMException(DOM_DOMException::NOT_SUPPORTED_ERR, null); } // If deep, replicate and attach the kids. if (deep) for (NodeImpl *srckid = source->getFirstChild(); srckid != null; srckid = srckid->getNextSibling()) { newnode->appendChild(importNode(srckid, true)); } if (newnode->getNodeType() == DOM_Node::ENTITY_REFERENCE_NODE || newnode->getNodeType() == DOM_Node::ENTITY_NODE) { ((EntityReferenceImpl*)newnode)->setReadOnly(true, true); errorChecking = oldErrorCheckingFlag; } return newnode;};ElementImpl *DocumentImpl::createElementNS(const DOMString &fNamespaceURI, const DOMString &qualifiedName){ if (errorChecking && !isXMLName(qualifiedName)) { throw DOM_DOMException(DOM_DOMException::INVALID_CHARACTER_ERR,null); } //DOMString pooledTagName = this->namePool->getPooledString(qualifiedName); return new (fMemoryManager) ElementNSImpl(this, fNamespaceURI, qualifiedName);}AttrImpl *DocumentImpl::createAttributeNS(const DOMString &fNamespaceURI, const DOMString &qualifiedName){ if (!isXMLName(qualifiedName)) { throw DOM_DOMException(DOM_DOMException::INVALID_CHARACTER_ERR,null); } return new (fMemoryManager) AttrNSImpl(this, fNamespaceURI, qualifiedName);}DeepNodeListImpl *DocumentImpl::getElementsByTagNameNS(const DOMString &fNamespaceURI, const DOMString &fLocalName){ return new (fMemoryManager) DeepNodeListImpl(this, fNamespaceURI, fLocalName);}ElementImpl *DocumentImpl::getElementById(const DOMString &elementId){ if (fNodeIDMap == 0) return null; AttrImpl *theAttr = fNodeIDMap->find(elementId); if (theAttr == null) return null; return theAttr->getOwnerElement();}//Return the index > 0 of ':' in the given qualified name qName="prefix:localName".//Return 0 if there is no ':', or -1 if qName is malformed such as ":abcd".int DocumentImpl::indexofQualifiedName(const DOMString & qName){ //Check if s = prefix:localName, name or malformed const XMLCh *qNameP = qName.rawBuffer(); int qNameLen = qName.length(); //note: qName[qNameLen] may not be 0 int index = -1, count = 0; for (int i = 0; i < qNameLen; ++i) if (*qNameP++ == chColon) { index = i; ++count; //number of ':' found } if (qNameLen == 0 || count > 1 || index == 0 || index == qNameLen-1) return -1; return count == 0 ? 0 : index;}XMLDeclImpl* DocumentImpl::createXMLDecl(const DOMString& version, const DOMString& encoding, const DOMString& standalone){ return new (fMemoryManager) XMLDeclImpl(this, version, encoding, standalone);}RangeImpl* DocumentImpl::createRange(){ RangeImpl* range = new (fMemoryManager) RangeImpl(DOM_Document(this)); if (ranges == 0L) { ranges = new (fMemoryManager) RangeImpls(1, false, fMemoryManager); } ranges->addElement(range); return range;}RangeImpls* DocumentImpl::getRanges(){ return ranges;}void DocumentImpl::removeRange(RangeImpl* range){ if (ranges != null) { unsigned int sz = ranges->size(); if (sz !=0) { for (unsigned int i =0; i<sz; i++) { if (ranges->elementAt(i) == range) { ranges->removeElementAt(i); delete range; break; } } } }}/** Uses the kidOK lookup table to check whether the proposed tree structure is legal. ????? It feels like there must be a more efficient solution, but for the life of me I can't think what it would be.*/bool DocumentImpl::isKidOK(NodeImpl *parent, NodeImpl *child){ static int kidOK[14]; if (kidOK[DOM_Node::DOCUMENT_NODE] == 0) { kidOK[DOM_Node::DOCUMENT_NODE] = 1 << DOM_Node::ELEMENT_NODE | 1 << DOM_Node::PROCESSING_INSTRUCTION_NODE | 1 << DOM_Node::COMMENT_NODE | 1 << DOM_Node::DOCUMENT_TYPE_NODE | 1 << DOM_Node::XML_DECL_NODE; kidOK[DOM_Node::DOCUMENT_FRAGMENT_NODE] = kidOK[DOM_Node::ENTITY_NODE] = kidOK[DOM_Node::ENTITY_REFERENCE_NODE] = kidOK[DOM_Node::ELEMENT_NODE] = 1 << DOM_Node::ELEMENT_NODE | 1 << DOM_Node::PROCESSING_INSTRUCTION_NODE | 1 << DOM_Node::COMMENT_NODE | 1 << DOM_Node::TEXT_NODE | 1 << DOM_Node::CDATA_SECTION_NODE | 1 << DOM_Node::ENTITY_REFERENCE_NODE | 1 << DOM_Node::XML_DECL_NODE; kidOK[DOM_Node::ATTRIBUTE_NODE] = 1 << DOM_Node::TEXT_NODE | 1 << DOM_Node::ENTITY_REFERENCE_NODE; kidOK[DOM_Node::PROCESSING_INSTRUCTION_NODE] = kidOK[DOM_Node::COMMENT_NODE] = kidOK[DOM_Node::TEXT_NODE] = kidOK[DOM_Node::CDATA_SECTION_NODE] = kidOK[DOM_Node::NOTATION_NODE] = 0; }; int p=parent->getNodeType(); int ch = child->getNodeType(); return (kidOK[p] & 1<<ch) != 0;}void DocumentImpl::setUserData(NodeImpl* n, void* data){ if (!userData && data) userData = new (fMemoryManager) RefHashTableOf<void> ( 29 , false , new (fMemoryManager) HashPtr() , fMemoryManager ); if (userData) { if (!data) userData->removeKey((void*)n); else userData->put((void*)n,data); }}void* DocumentImpl::getUserData(NodeImpl* n){ if (userData) return userData->get((void*)n); else return null;}void* DocumentImpl::getUserData(){ return (hasUserData()) ? getUserData(this) : null;}void DocumentImpl::setUserData(void* val){ setUserData(this, val); if (val) hasUserData(true); else hasUserData(false);};/** * Denotes that this node has changed. */void DocumentImpl::changed() { fChanges++;}/** * Returns the number of changes to this node. */int DocumentImpl::changes() { return fChanges;}// -----------------------------------------------------------------------// Notification that lazy data has been deleted// -----------------------------------------------------------------------void DocumentImpl::reinitDocumentImpl() { delete nam; nam = 0;}XERCES_CPP_NAMESPACE_END
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?