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 + -
显示快捷键?