domattrmapimpl.cpp

来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 448 行

CPP
448
字号
/* * Copyright 2001-2002,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: DOMAttrMapImpl.cpp,v 1.8 2004/09/08 13:55:50 peiyongz Exp $ */#include "DOMAttrMapImpl.hpp"#include "DOMAttrImpl.hpp"#include "DOMNodeImpl.hpp"#include "DOMElementImpl.hpp"#include "DOMCasts.hpp"#include "DOMNodeVector.hpp"#include <xercesc/dom/DOMAttr.hpp>#include <xercesc/dom/DOMException.hpp>XERCES_CPP_NAMESPACE_BEGINDOMAttrMapImpl::DOMAttrMapImpl(DOMNode *ownerNod){    this->fOwnerNode=ownerNod;    this->fNodes = 0;	hasDefaults(false);}DOMAttrMapImpl::DOMAttrMapImpl(DOMNode *ownerNod, const DOMAttrMapImpl *defaults){    this->fOwnerNode=ownerNod;    this->fNodes = 0;	hasDefaults(false);	if (defaults != 0)	{		if (defaults->getLength() > 0)		{			hasDefaults(true);			cloneContent(defaults);		}	}}DOMAttrMapImpl::~DOMAttrMapImpl(){}void DOMAttrMapImpl::cloneContent(const DOMAttrMapImpl *srcmap){    if ((srcmap != 0) && (srcmap->fNodes != 0))    {        if (fNodes != 0)            fNodes->reset();        else        {            XMLSize_t size = srcmap->fNodes->size();            if(size > 0) {                DOMDocument *doc = fOwnerNode->getOwnerDocument();                fNodes = new (doc) DOMNodeVector(doc, size);            }        }        for (XMLSize_t i = 0; i < srcmap->fNodes->size(); i++)        {            DOMNode *n = srcmap->fNodes->elementAt(i);            DOMNode *clone = n->cloneNode(true);            castToNodeImpl(clone)->isSpecified(castToNodeImpl(n)->isSpecified());            castToNodeImpl(clone)->fOwnerNode = fOwnerNode;            castToNodeImpl(clone)->isOwned(true);            fNodes->addElement(clone);        }    }}DOMAttrMapImpl *DOMAttrMapImpl::cloneAttrMap(DOMNode *ownerNode_p){	DOMAttrMapImpl *newmap = new (castToNodeImpl(ownerNode_p)->getOwnerDocument()) DOMAttrMapImpl(ownerNode_p);	newmap->cloneContent(this);	// newmap->attrDefaults = this->attrDefaults;  // revisit	return newmap;}void DOMAttrMapImpl::setReadOnly(bool readOnl, bool deep){    // this->fReadOnly=readOnl;    if(deep && fNodes!=0)    {        int sz = fNodes->size();        for (int i=0; i<sz; ++i) {            castToNodeImpl(fNodes->elementAt(i))->setReadOnly(readOnl, deep);        }    }}bool DOMAttrMapImpl::readOnly() {    return castToNodeImpl(fOwnerNode)->isReadOnly();}int DOMAttrMapImpl::findNamePoint(const XMLCh *name) const{    // Binary search    int i=0;    if(fNodes!=0)    {        int first=0,last=fNodes->size()-1;        while(first<=last)        {            i=(first+last)/2;            int test = XMLString::compareString(name, fNodes->elementAt(i)->getNodeName());            if(test==0)                return i; // Name found            else if(test<0)                last=i-1;            else                first=i+1;        }        if(first>i) i=first;    }    /********************    // Linear search    int i = 0;    if (fNodes != 0)    for (i = 0; i < fNodes.size(); ++i)    {    int test = name.compareTo(((NodeImpl *) (fNodes.elementAt(i))).getNodeName());    if (test == 0)    return i;    else    if (test < 0)    {    break; // Found insertpoint    }    }    *******************/    return -1 - i; // not-found has to be encoded.}DOMNode * DOMAttrMapImpl::getNamedItem(const XMLCh *name) const{    int i=findNamePoint(name);    return (i<0) ? 0 : fNodes->elementAt(i);}DOMNode *DOMAttrMapImpl::setNamedItem(DOMNode *arg){    if (arg->getNodeType() != DOMNode::ATTRIBUTE_NODE)        throw DOMException(DOMException::HIERARCHY_REQUEST_ERR, 0, GetDOMNamedNodeMapMemoryManager);    DOMDocument *doc = fOwnerNode->getOwnerDocument();    DOMNodeImpl *argImpl = castToNodeImpl(arg);    if(argImpl->getOwnerDocument() != doc)        throw DOMException(DOMException::WRONG_DOCUMENT_ERR, 0, GetDOMNamedNodeMapMemoryManager);    if (this->readOnly())        throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNamedNodeMapMemoryManager);    if ((arg->getNodeType() == DOMNode::ATTRIBUTE_NODE) && argImpl->isOwned() && (argImpl->fOwnerNode != fOwnerNode))        throw DOMException(DOMException::INUSE_ATTRIBUTE_ERR,0, GetDOMNamedNodeMapMemoryManager);    argImpl->fOwnerNode = fOwnerNode;    argImpl->isOwned(true);    int i=findNamePoint(arg->getNodeName());    DOMNode * previous=0;    if(i>=0)    {        previous = fNodes->elementAt(i);        fNodes->setElementAt(arg,i);    }    else    {        i=-1-i; // Insert point (may be end of list)        if(0==fNodes)        {            fNodes=new (doc) DOMNodeVector(doc);        }        fNodes->insertElementAt(arg,i);    }    if (previous != 0) {        castToNodeImpl(previous)->fOwnerNode = fOwnerNode->getOwnerDocument();        castToNodeImpl(previous)->isOwned(false);    }    return previous;}//Introduced in DOM Level 2int DOMAttrMapImpl::findNamePoint(const XMLCh *namespaceURI,	const XMLCh *localName) const{    if (fNodes == 0)	return -1;    // This is a linear search through the same fNodes Vector.    // The Vector is sorted on the DOM Level 1 nodename.    // The DOM Level 2 NS keys are namespaceURI and Localname,    // so we must linear search thru it.    // In addition, to get this to work with fNodes without any namespace    // (namespaceURI and localNames are both 0) we then use the nodeName    // as a secondary key.    int i, len = fNodes -> size();    for (i = 0; i < len; ++i) {        DOMNode *node = fNodes -> elementAt(i);        const XMLCh * nNamespaceURI = node->getNamespaceURI();        const XMLCh * nLocalName = node->getLocalName();        if (!XMLString::equals(nNamespaceURI, namespaceURI))    //URI not match            continue;        else {            if (XMLString::equals(localName, nLocalName)                ||                (nLocalName == 0 && XMLString::equals(localName, node->getNodeName())))                return i;        }    }    return -1;	//not found}DOMNode *DOMAttrMapImpl::getNamedItemNS(const XMLCh *namespaceURI,	const XMLCh *localName) const{    int i = findNamePoint(namespaceURI, localName);    return i < 0 ? 0 : fNodes -> elementAt(i);}DOMNode *DOMAttrMapImpl::setNamedItemNS(DOMNode* arg){    if (arg->getNodeType() != DOMNode::ATTRIBUTE_NODE)        throw DOMException(DOMException::HIERARCHY_REQUEST_ERR, 0, GetDOMNamedNodeMapMemoryManager);    DOMDocument *doc = fOwnerNode->getOwnerDocument();    DOMNodeImpl *argImpl = castToNodeImpl(arg);    if (argImpl->getOwnerDocument() != doc)        throw DOMException(DOMException::WRONG_DOCUMENT_ERR,0, GetDOMNamedNodeMapMemoryManager);    if (this->readOnly())        throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNamedNodeMapMemoryManager);    if (argImpl->isOwned())        throw DOMException(DOMException::INUSE_ATTRIBUTE_ERR,0, GetDOMNamedNodeMapMemoryManager);    argImpl->fOwnerNode = fOwnerNode;    argImpl->isOwned(true);    int i=findNamePoint(arg->getNamespaceURI(), arg->getLocalName());    DOMNode *previous=0;    if(i>=0) {        previous = fNodes->elementAt(i);        fNodes->setElementAt(arg,i);    } else {        i=findNamePoint(arg->getNodeName()); // Insert point (may be end of list)        if (i<0)          i = -1 - i;        if(0==fNodes)            fNodes=new (doc) DOMNodeVector(doc);        fNodes->insertElementAt(arg,i);    }    if (previous != 0) {        castToNodeImpl(previous)->fOwnerNode = fOwnerNode->getOwnerDocument();        castToNodeImpl(previous)->isOwned(false);    }    return previous;}DOMNode *DOMAttrMapImpl::removeNamedItem(const XMLCh *name){    if (this->readOnly())        throw DOMException(            DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNamedNodeMapMemoryManager);    int i=findNamePoint(name);    DOMNode *removed = 0;    if(i<0)        throw DOMException(DOMException::NOT_FOUND_ERR, 0, GetDOMNamedNodeMapMemoryManager);    removed = fNodes->elementAt(i);    fNodes->removeElementAt(i);    castToNodeImpl(removed)->fOwnerNode = fOwnerNode->getOwnerDocument();    castToNodeImpl(removed)->isOwned(false);    // Replace it if it had a default value    // (DOM spec level 1 - Element Interface)    if (hasDefaults() && (removed != 0))    {        DOMAttrMapImpl* defAttrs = ((DOMElementImpl*)fOwnerNode)->getDefaultAttributes();        DOMAttr* attr = (DOMAttr*)(defAttrs->getNamedItem(name));        if (attr != 0)        {            DOMAttr* newAttr = (DOMAttr*)attr->cloneNode(true);            setNamedItem(newAttr);        }    }    return removed;}DOMNode *DOMAttrMapImpl::removeNamedItemNS(const XMLCh *namespaceURI, const XMLCh *localName){    if (this->readOnly())        throw DOMException(        DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNamedNodeMapMemoryManager);    int i = findNamePoint(namespaceURI, localName);    if (i < 0)        throw DOMException(DOMException::NOT_FOUND_ERR, 0, GetDOMNamedNodeMapMemoryManager);    DOMNode * removed = fNodes -> elementAt(i);    fNodes -> removeElementAt(i);	//remove n from nodes    castToNodeImpl(removed)->fOwnerNode = fOwnerNode->getOwnerDocument();    castToNodeImpl(removed)->isOwned(false);    // Replace it if it had a default value    // (DOM spec level 2 - Element Interface)    if (hasDefaults() && (removed != 0))    {        DOMAttrMapImpl* defAttrs = ((DOMElementImpl*)fOwnerNode)->getDefaultAttributes();        DOMAttr* attr = (DOMAttr*)(defAttrs->getNamedItemNS(namespaceURI, localName));        if (attr != 0)        {            DOMAttr* newAttr = (DOMAttr*)attr->cloneNode(true);            setNamedItemNS(newAttr);        }    }    return removed;}// remove the name using index// avoid calling findNamePoint again if the index is already knownDOMNode * DOMAttrMapImpl::removeNamedItemAt(XMLSize_t index){    if (this->readOnly())        throw DOMException(            DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNamedNodeMapMemoryManager);    DOMNode *removed = item(index);    if(!removed)        throw DOMException(DOMException::NOT_FOUND_ERR, 0, GetDOMNamedNodeMapMemoryManager);    fNodes->removeElementAt(index);    castToNodeImpl(removed)->fOwnerNode = fOwnerNode->getOwnerDocument();    castToNodeImpl(removed)->isOwned(false);    // Replace it if it had a default value    // (DOM spec level 1 - Element Interface)    if (hasDefaults() && (removed != 0))    {        DOMAttrMapImpl* defAttrs = ((DOMElementImpl*)fOwnerNode)->getDefaultAttributes();        const XMLCh* localName = removed->getLocalName();        DOMAttr* attr = 0;        if (localName)            attr = (DOMAttr*)(defAttrs->getNamedItemNS(removed->getNamespaceURI(), localName));        else            attr = (DOMAttr*)(defAttrs->getNamedItem(((DOMAttr*)removed)->getName()));        if (attr != 0)        {            DOMAttr* newAttr = (DOMAttr*)attr->cloneNode(true);            setNamedItem(newAttr);        }    }    return removed;}/** * Get this AttributeMap in sync with the given "defaults" map. * @param defaults The default attributes map to sync with. */void DOMAttrMapImpl::reconcileDefaultAttributes(const DOMAttrMapImpl* defaults) {    // remove any existing default    XMLSize_t nsize = getLength();    for (XMLSSize_t i = nsize - 1; i >= 0; i--) {        DOMAttr* attr = (DOMAttr*)item(i);        if (!attr->getSpecified()) {            removeNamedItemAt(i);        }    }    hasDefaults(false);    // add the new defaults    if (defaults) {        hasDefaults(true);        if (nsize == 0) {            cloneContent(defaults);        }        else {            XMLSize_t dsize = defaults->getLength();            for (XMLSize_t n = 0; n < dsize; n++) {                DOMAttr* attr = (DOMAttr*)defaults->item(n);                DOMAttr* newAttr = (DOMAttr*)attr->cloneNode(true);                setNamedItemNS(newAttr);                DOMAttrImpl* newAttrImpl = (DOMAttrImpl*) newAttr;                newAttrImpl->setSpecified(false);            }        }    }} // reconcileDefaults()/** * Move specified attributes from the given map to this one */void DOMAttrMapImpl::moveSpecifiedAttributes(DOMAttrMapImpl* srcmap) {    XMLSize_t nsize = srcmap->getLength();    for (XMLSSize_t i = nsize - 1; i >= 0; i--) {        DOMAttr* attr = (DOMAttr*)srcmap->item(i);        if (attr->getSpecified()) {            srcmap->removeNamedItemAt(i);        }        if (attr->getLocalName())            setNamedItemNS(attr);        else            setNamedItem(attr);    }} // moveSpecifiedAttributes(AttributeMap):voidXMLSize_t DOMAttrMapImpl::getLength() const{    return (fNodes != 0) ? fNodes->size() : 0;}DOMNode * DOMAttrMapImpl::item(XMLSize_t index) const{    return (fNodes != 0 && index < fNodes->size()) ?        fNodes->elementAt(index) : 0;}XERCES_CPP_NAMESPACE_END

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?