GME
13
|
00001 /* 00002 * Licensed to the Apache Software Foundation (ASF) under one or more 00003 * contributor license agreements. See the NOTICE file distributed with 00004 * this work for additional information regarding copyright ownership. 00005 * The ASF licenses this file to You under the Apache License, Version 2.0 00006 * (the "License"); you may not use this file except in compliance with 00007 * the License. You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 /* 00019 * $Id: DOMElementImpl.cpp 901107 2010-01-20 08:45:02Z borisk $ 00020 */ 00021 00022 #include "DOMElementImpl.hpp" 00023 00024 #include <xercesc/dom/DOMAttr.hpp> 00025 #include <xercesc/dom/DOMDocument.hpp> 00026 #include <xercesc/dom/DOMException.hpp> 00027 #include <xercesc/util/XMLUniDefs.hpp> 00028 #include <xercesc/util/XMLUri.hpp> 00029 00030 #include "DOMAttrMapImpl.hpp" 00031 #include "DOMAttrImpl.hpp" 00032 #include "DOMDocumentImpl.hpp" 00033 #include "DOMParentNode.hpp" 00034 #include "DOMCasts.hpp" 00035 #include "DOMElementNSImpl.hpp" 00036 #include "DOMTypeInfoImpl.hpp" 00037 00038 #include "DOMDocumentTypeImpl.hpp" 00039 #include <xercesc/util/OutOfMemoryException.hpp> 00040 00041 XERCES_CPP_NAMESPACE_BEGIN 00042 00043 class DOMAttr; 00044 00045 DOMElementImpl::DOMElementImpl(DOMDocument *ownerDoc, const XMLCh *eName) 00046 : fNode(ownerDoc), fParent(ownerDoc), fAttributes(0), fDefaultAttributes(0) 00047 { 00048 DOMDocumentImpl *docImpl = (DOMDocumentImpl *)ownerDoc; 00049 fName = docImpl->getPooledString(eName); 00050 setupDefaultAttributes(); 00051 if (!fDefaultAttributes) { 00052 fDefaultAttributes = new (docImpl) DOMAttrMapImpl(this); 00053 fAttributes = new (docImpl) DOMAttrMapImpl(this); 00054 } 00055 else { 00056 fAttributes = new (docImpl) DOMAttrMapImpl(this, fDefaultAttributes); 00057 } 00058 } 00059 00060 00061 DOMElementImpl::DOMElementImpl(const DOMElementImpl &other, bool deep) 00062 : DOMElement(other), 00063 fNode (other.fParent.fOwnerDocument), 00064 fParent (other.fParent.fOwnerDocument), 00065 fAttributes(0), 00066 fDefaultAttributes(0) 00067 { 00068 fName = other.fName; 00069 00070 if (deep) 00071 fParent.cloneChildren(&other); 00072 00073 if (other.getAttributes()) 00074 { 00075 fAttributes = ((DOMAttrMapImpl *)other.getAttributes())->cloneAttrMap(this); 00076 } 00077 00078 if (other.getDefaultAttributes()) 00079 { 00080 fDefaultAttributes = ((DOMAttrMapImpl *)other.getDefaultAttributes())->cloneAttrMap(this); 00081 } 00082 00083 if (!fDefaultAttributes) 00084 setupDefaultAttributes(); 00085 00086 if (!fDefaultAttributes) 00087 fDefaultAttributes = new (fParent.fOwnerDocument) DOMAttrMapImpl(this); 00088 00089 if (!fAttributes) { 00090 if (!fDefaultAttributes) { 00091 fAttributes = new (fParent.fOwnerDocument) DOMAttrMapImpl(this); 00092 } 00093 else { 00094 fAttributes = new (fParent.fOwnerDocument) DOMAttrMapImpl(this, fDefaultAttributes); 00095 } 00096 } 00097 00098 } 00099 00100 00101 DOMElementImpl::~DOMElementImpl() 00102 { 00103 } 00104 00105 00106 DOMNode *DOMElementImpl::cloneNode(bool deep) const 00107 { 00108 DOMNode* newNode = new (fParent.fOwnerDocument, DOMMemoryManager::ELEMENT_OBJECT) DOMElementImpl(*this, deep); 00109 fNode.callUserDataHandlers(DOMUserDataHandler::NODE_CLONED, this, newNode); 00110 return newNode; 00111 } 00112 00113 00114 00115 00116 const XMLCh * DOMElementImpl::getNodeName() const { 00117 return fName; 00118 } 00119 00120 00121 DOMNode::NodeType DOMElementImpl::getNodeType() const { 00122 return DOMNode::ELEMENT_NODE; 00123 } 00124 00125 00126 const XMLCh * DOMElementImpl::getAttribute(const XMLCh *nam) const 00127 { 00128 DOMNode * attr = fAttributes->getNamedItem(nam); 00129 if (attr) 00130 return attr->getNodeValue(); 00131 00132 return XMLUni::fgZeroLenString; 00133 } 00134 00135 00136 00137 DOMAttr *DOMElementImpl::getAttributeNode(const XMLCh *nam) const 00138 { 00139 return (DOMAttr *)fAttributes->getNamedItem(nam); 00140 } 00141 00142 00143 DOMNamedNodeMap *DOMElementImpl::getAttributes() const 00144 { 00145 DOMElementImpl *ncThis = (DOMElementImpl *)this; // cast off const 00146 return ncThis->fAttributes; 00147 } 00148 00149 00150 00151 DOMNodeList *DOMElementImpl::getElementsByTagName(const XMLCh *tagname) const 00152 { 00153 DOMDocumentImpl *docImpl = (DOMDocumentImpl *)fParent.fOwnerDocument; 00154 return docImpl->getDeepNodeList(this,tagname); 00155 } 00156 00157 00158 const XMLCh * DOMElementImpl::getTagName() const 00159 { 00160 return fName; 00161 } 00162 00163 00164 void DOMElementImpl::removeAttribute(const XMLCh *nam) 00165 { 00166 if (fNode.isReadOnly()) 00167 throw DOMException( 00168 DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager); 00169 00170 int i = fAttributes->findNamePoint(nam); 00171 if (i >= 0) 00172 { 00173 DOMNode *att = fAttributes->removeNamedItemAt(i); 00174 ((DOMAttrImpl *)att)->removeAttrFromIDNodeMap(); 00175 att->release(); 00176 } 00177 } 00178 00179 00180 00181 DOMAttr *DOMElementImpl::removeAttributeNode(DOMAttr *oldAttr) 00182 { 00183 if (fNode.isReadOnly()) 00184 throw DOMException( 00185 DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager); 00186 00187 DOMNode* found = 0; 00188 00189 // Since there is no removeAttributeNodeNS, check if this oldAttr has NS or not 00190 const XMLCh* localName = oldAttr->getLocalName(); 00191 int i = 0; 00192 if (localName) 00193 i = fAttributes->findNamePoint(oldAttr->getNamespaceURI(), localName); 00194 else 00195 i = fAttributes->findNamePoint(oldAttr->getName()); 00196 00197 if (i >= 0) { 00198 // If it is in fact the right object, remove it. 00199 found = fAttributes->item(i); 00200 if (found == oldAttr) { 00201 fAttributes->removeNamedItemAt(i); 00202 ((DOMAttrImpl *)oldAttr)->removeAttrFromIDNodeMap(); 00203 } 00204 else 00205 throw DOMException(DOMException::NOT_FOUND_ERR, 0, GetDOMNodeMemoryManager); 00206 00207 } 00208 else 00209 throw DOMException(DOMException::NOT_FOUND_ERR, 0, GetDOMNodeMemoryManager); 00210 00211 return (DOMAttr *)found; 00212 } 00213 00214 00215 00216 void DOMElementImpl::setAttribute(const XMLCh *nam, const XMLCh *val) 00217 { 00218 if (fNode.isReadOnly()) 00219 throw DOMException( 00220 DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager); 00221 00222 DOMAttr* newAttr = getAttributeNode(nam); 00223 if (!newAttr) 00224 { 00225 newAttr = fParent.fOwnerDocument->createAttribute(nam); 00226 fAttributes->setNamedItem(newAttr); 00227 } 00228 00229 newAttr->setNodeValue(val); 00230 } 00231 00232 void DOMElementImpl::setIdAttribute(const XMLCh* name, bool isId) 00233 { 00234 if (fNode.isReadOnly()) 00235 throw DOMException( 00236 DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager); 00237 00238 DOMAttr *attr = getAttributeNode(name); 00239 00240 if (!attr) 00241 throw DOMException(DOMException::NOT_FOUND_ERR, 0, GetDOMNodeMemoryManager); 00242 00243 if(isId) 00244 ((DOMAttrImpl *)attr)->addAttrToIDNodeMap(); 00245 else 00246 ((DOMAttrImpl *)attr)->removeAttrFromIDNodeMap(); 00247 } 00248 00249 void DOMElementImpl::setIdAttributeNS(const XMLCh* namespaceURI, const XMLCh* localName, bool isId) { 00250 00251 if (fNode.isReadOnly()) 00252 throw DOMException( 00253 DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager); 00254 00255 DOMAttr *attr = getAttributeNodeNS(namespaceURI, localName); 00256 00257 if (!attr) 00258 throw DOMException(DOMException::NOT_FOUND_ERR, 0, GetDOMNodeMemoryManager); 00259 00260 if(isId) 00261 ((DOMAttrImpl *)attr)->addAttrToIDNodeMap(); 00262 else 00263 ((DOMAttrImpl *)attr)->removeAttrFromIDNodeMap(); 00264 } 00265 00266 00267 void DOMElementImpl::setIdAttributeNode(const DOMAttr *idAttr, bool isId) { 00268 00269 if (fNode.isReadOnly()) 00270 throw DOMException( 00271 DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager); 00272 00273 DOMAttr *attr; 00274 const XMLCh* localName = idAttr->getLocalName(); 00275 if (localName) 00276 attr = getAttributeNodeNS(idAttr->getNamespaceURI(), idAttr->getLocalName()); 00277 else 00278 attr = getAttributeNode(idAttr->getName()); 00279 00280 if(!attr) 00281 throw DOMException(DOMException::NOT_FOUND_ERR, 0, GetDOMNodeMemoryManager); 00282 00283 if(isId) 00284 ((DOMAttrImpl *)attr)->addAttrToIDNodeMap(); 00285 else 00286 ((DOMAttrImpl *)attr)->removeAttrFromIDNodeMap(); 00287 } 00288 00289 00290 DOMAttr * DOMElementImpl::setAttributeNode(DOMAttr *newAttr) 00291 { 00292 if (fNode.isReadOnly()) 00293 throw DOMException( 00294 DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager); 00295 00296 if (newAttr->getNodeType() != DOMNode::ATTRIBUTE_NODE) 00297 throw DOMException(DOMException::WRONG_DOCUMENT_ERR, 0, GetDOMNodeMemoryManager); 00298 // revisit. Exception doesn't match test. 00299 00300 // This will throw INUSE if necessary 00301 DOMAttr *oldAttr = (DOMAttr *) fAttributes->setNamedItem(newAttr); 00302 00303 return oldAttr; 00304 } 00305 00306 00307 void DOMElementImpl::setNodeValue(const XMLCh *x) 00308 { 00309 fNode.setNodeValue(x); 00310 } 00311 00312 00313 00314 void DOMElementImpl::setReadOnly(bool readOnl, bool deep) 00315 { 00316 fNode.setReadOnly(readOnl,deep); 00317 fAttributes->setReadOnly(readOnl,true); 00318 } 00319 00320 00321 //Introduced in DOM Level 2 00322 const XMLCh * DOMElementImpl::getAttributeNS(const XMLCh *fNamespaceURI, 00323 const XMLCh *fLocalName) const 00324 { 00325 DOMAttr * attr= 00326 (DOMAttr *)(fAttributes->getNamedItemNS(fNamespaceURI, fLocalName)); 00327 return (attr==0) ? XMLUni::fgZeroLenString : attr->getValue(); 00328 } 00329 00330 00331 void DOMElementImpl::setAttributeNS(const XMLCh *fNamespaceURI, 00332 const XMLCh *qualifiedName, const XMLCh *fValue) 00333 { 00334 if (fNode.isReadOnly()) 00335 throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager); 00336 00337 int index = DOMDocumentImpl::indexofQualifiedName(qualifiedName); 00338 if (index < 0) 00339 throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager); 00340 00341 DOMAttr* newAttr = getAttributeNodeNS(fNamespaceURI, qualifiedName+index); 00342 if (!newAttr) 00343 { 00344 newAttr = fParent.fOwnerDocument->createAttributeNS(fNamespaceURI, qualifiedName); 00345 fAttributes->setNamedItemNS(newAttr); 00346 } 00347 00348 newAttr->setNodeValue(fValue); 00349 } 00350 00351 00352 void DOMElementImpl::removeAttributeNS(const XMLCh *fNamespaceURI, 00353 const XMLCh *fLocalName) 00354 { 00355 if (fNode.isReadOnly()) 00356 throw DOMException( 00357 DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager); 00358 00359 int i = fAttributes->findNamePoint(fNamespaceURI, fLocalName); 00360 if (i >= 0) 00361 { 00362 DOMNode *att = fAttributes->removeNamedItemAt(i); 00363 att->release(); 00364 } 00365 } 00366 00367 00368 DOMAttr *DOMElementImpl::getAttributeNodeNS(const XMLCh *fNamespaceURI, 00369 const XMLCh *fLocalName) const 00370 { 00371 return (DOMAttr *)fAttributes->getNamedItemNS(fNamespaceURI, fLocalName); 00372 } 00373 00374 00375 DOMAttr *DOMElementImpl::setAttributeNodeNS(DOMAttr *newAttr) 00376 { 00377 if (fNode.isReadOnly()) 00378 throw DOMException( 00379 DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager); 00380 00381 if (newAttr -> getOwnerDocument() != fParent.fOwnerDocument) 00382 throw DOMException(DOMException::WRONG_DOCUMENT_ERR, 0, GetDOMNodeMemoryManager); 00383 00384 // This will throw INUSE if necessary 00385 DOMAttr *oldAttr = (DOMAttr *) fAttributes->setNamedItemNS(newAttr); 00386 00387 return oldAttr; 00388 } 00389 00390 00391 DOMNodeList *DOMElementImpl::getElementsByTagNameNS(const XMLCh *namespaceURI, 00392 const XMLCh *localName) const 00393 { 00394 DOMDocumentImpl *docImpl = (DOMDocumentImpl *)fParent.fOwnerDocument; 00395 return docImpl->getDeepNodeList(this, namespaceURI, localName); 00396 } 00397 00398 bool DOMElementImpl::hasAttributes() const 00399 { 00400 return (fAttributes != 0 && fAttributes->getLength() != 0); 00401 } 00402 00403 00404 bool DOMElementImpl::hasAttribute(const XMLCh *name) const 00405 { 00406 return (getAttributeNode(name) != 0); 00407 } 00408 00409 00410 bool DOMElementImpl::hasAttributeNS(const XMLCh *namespaceURI, 00411 const XMLCh *localName) const 00412 { 00413 return (getAttributeNodeNS(namespaceURI, localName) != 0); 00414 } 00415 00416 00417 // util functions for default attributes 00418 // returns the default attribute map for this node from the owner document 00419 DOMAttrMapImpl *DOMElementImpl::getDefaultAttributes() const 00420 { 00421 return fDefaultAttributes; 00422 } 00423 00424 // initially set up the default attribute information based on doctype information 00425 void DOMElementImpl::setupDefaultAttributes() 00426 { 00427 DOMDocument *tmpdoc = fParent.fOwnerDocument; 00428 if ((fNode.fOwnerNode == 0) || (tmpdoc == 0) || (tmpdoc->getDoctype() == 0)) 00429 return; 00430 00431 DOMNode *eldef = ((DOMDocumentTypeImpl*)tmpdoc->getDoctype())->getElements()->getNamedItem(getNodeName()); 00432 DOMAttrMapImpl* defAttrs = (eldef == 0) ? 0 : (DOMAttrMapImpl *)(eldef->getAttributes()); 00433 00434 if (defAttrs) 00435 fDefaultAttributes = new (tmpdoc) DOMAttrMapImpl(this, defAttrs); 00436 } 00437 00438 DOMAttr * DOMElementImpl::setDefaultAttributeNode(DOMAttr *newAttr) 00439 { 00440 if (fNode.isReadOnly()) 00441 throw DOMException( 00442 DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager); 00443 00444 if (newAttr->getNodeType() != DOMNode::ATTRIBUTE_NODE) 00445 throw DOMException(DOMException::WRONG_DOCUMENT_ERR, 0, GetDOMNodeMemoryManager); 00446 // revisit. Exception doesn't match test. 00447 00448 // This will throw INUSE if necessary 00449 DOMAttr *oldAttr = (DOMAttr *) fDefaultAttributes->setNamedItem(newAttr); 00450 fAttributes->hasDefaults(true); 00451 00452 return oldAttr; 00453 } 00454 00455 00456 DOMAttr *DOMElementImpl::setDefaultAttributeNodeNS(DOMAttr *newAttr) 00457 { 00458 if (fNode.isReadOnly()) 00459 throw DOMException( 00460 DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager); 00461 00462 if (newAttr -> getOwnerDocument() != fParent.fOwnerDocument) 00463 throw DOMException(DOMException::WRONG_DOCUMENT_ERR, 0, GetDOMNodeMemoryManager); 00464 00465 // This will throw INUSE if necessary 00466 DOMAttr *oldAttr = (DOMAttr *) fDefaultAttributes->setNamedItemNS(newAttr); 00467 fAttributes->hasDefaults(true); 00468 00469 return oldAttr; 00470 } 00471 00472 void DOMElementImpl::release() 00473 { 00474 if (fNode.isOwned() && !fNode.isToBeReleased()) 00475 throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager); 00476 00477 DOMDocumentImpl* doc = (DOMDocumentImpl*) fParent.fOwnerDocument; 00478 if (doc) { 00479 fNode.callUserDataHandlers(DOMUserDataHandler::NODE_DELETED, 0, 0); 00480 // release children 00481 fParent.release(); 00482 // release attributes 00483 fAttributes->hasDefaults(false); 00484 XMLSize_t count; 00485 while((count = fAttributes->getLength()) != 0) 00486 { 00487 DOMNode* attr = fAttributes->removeNamedItemAt(count-1); 00488 attr->release(); 00489 } 00490 00491 doc->release(this, DOMMemoryManager::ELEMENT_OBJECT); 00492 } 00493 else { 00494 // shouldn't reach here 00495 throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager); 00496 } 00497 } 00498 00499 const XMLCh* DOMElementImpl::getBaseURI() const 00500 { 00501 const XMLCh* baseURI = fNode.fOwnerNode->getBaseURI(); 00502 if (fAttributes) { 00503 const XMLCh baseString[] = 00504 { 00505 chLatin_b, chLatin_a, chLatin_s, chLatin_e, chNull 00506 }; 00507 DOMNode* attrNode = fAttributes->getNamedItemNS(DOMNodeImpl::getXmlURIString(), baseString); 00508 if (attrNode==NULL) { 00509 const XMLCh xmlBaseString[] = 00510 { 00511 chLatin_x, chLatin_m, chLatin_l, chColon, chLatin_b, chLatin_a, chLatin_s, chLatin_e, chNull 00512 }; 00513 attrNode = fAttributes->getNamedItem(xmlBaseString); 00514 } 00515 if (attrNode) { 00516 const XMLCh* uri = attrNode->getNodeValue(); 00517 if (uri && *uri) {// attribute value is always empty string 00518 // if there is a base URI for the parent node, use it to resolve relative URI 00519 if(baseURI) 00520 { 00521 try { 00522 DOMDocumentImpl* doc = (DOMDocumentImpl *)fParent.fOwnerDocument; 00523 XMLUri temp(baseURI, doc->getMemoryManager()); 00524 XMLUri temp2(&temp, uri, doc->getMemoryManager()); 00525 uri = doc->cloneString(temp2.getUriText()); 00526 } 00527 catch(const OutOfMemoryException&) 00528 { 00529 throw; 00530 } 00531 catch (...){ 00532 // REVISIT: what should happen in this case? 00533 return 0; 00534 } 00535 } 00536 return uri; 00537 } 00538 } 00539 } 00540 return baseURI; 00541 } 00542 00543 00544 00545 // 00546 // Functions inherited from Node 00547 // 00548 DOMNode* DOMElementImpl::appendChild(DOMNode *newChild) {return fParent.appendChild (newChild); } 00549 DOMNodeList* DOMElementImpl::getChildNodes() const {return fParent.getChildNodes (); } 00550 DOMNode* DOMElementImpl::getFirstChild() const {return fParent.getFirstChild (); } 00551 DOMNode* DOMElementImpl::getLastChild() const {return fParent.getLastChild (); } 00552 const XMLCh* DOMElementImpl::getLocalName() const {return fNode.getLocalName (); } 00553 const XMLCh* DOMElementImpl::getNamespaceURI() const {return fNode.getNamespaceURI (); } 00554 DOMNode* DOMElementImpl::getNextSibling() const {return fChild.getNextSibling (); } 00555 const XMLCh* DOMElementImpl::getNodeValue() const {return fNode.getNodeValue (); } 00556 DOMDocument* DOMElementImpl::getOwnerDocument() const {return fParent.fOwnerDocument; } 00557 const XMLCh* DOMElementImpl::getPrefix() const {return fNode.getPrefix (); } 00558 DOMNode* DOMElementImpl::getParentNode() const {return fChild.getParentNode (this); } 00559 DOMNode* DOMElementImpl::getPreviousSibling() const {return fChild.getPreviousSibling (this); } 00560 bool DOMElementImpl::hasChildNodes() const {return fParent.hasChildNodes (); } 00561 DOMNode* DOMElementImpl::insertBefore(DOMNode *newChild, DOMNode *refChild) 00562 {return fParent.insertBefore (newChild, refChild); } 00563 void DOMElementImpl::normalize() {fParent.normalize (); } 00564 DOMNode* DOMElementImpl::removeChild(DOMNode *oldChild) {return fParent.removeChild (oldChild); } 00565 DOMNode* DOMElementImpl::replaceChild(DOMNode *newChild, DOMNode *oldChild) 00566 {return fParent.replaceChild (newChild, oldChild); } 00567 bool DOMElementImpl::isSupported(const XMLCh *feature, const XMLCh *version) const 00568 {return fNode.isSupported (feature, version); } 00569 void DOMElementImpl::setPrefix(const XMLCh *prefix) {fNode.setPrefix(prefix); } 00570 bool DOMElementImpl::isSameNode(const DOMNode* other) const {return fNode.isSameNode(other); } 00571 void* DOMElementImpl::setUserData(const XMLCh* key, void* data, DOMUserDataHandler* handler) 00572 {return fNode.setUserData(key, data, handler); } 00573 void* DOMElementImpl::getUserData(const XMLCh* key) const {return fNode.getUserData(key); } 00574 short DOMElementImpl::compareDocumentPosition(const DOMNode* other) const {return fNode.compareDocumentPosition(other); } 00575 const XMLCh* DOMElementImpl::getTextContent() const {return fNode.getTextContent(); } 00576 void DOMElementImpl::setTextContent(const XMLCh* textContent){fNode.setTextContent(textContent); } 00577 const XMLCh* DOMElementImpl::lookupPrefix(const XMLCh* namespaceURI) const {return fNode.lookupPrefix(namespaceURI); } 00578 bool DOMElementImpl::isDefaultNamespace(const XMLCh* namespaceURI) const {return fNode.isDefaultNamespace(namespaceURI); } 00579 const XMLCh* DOMElementImpl::lookupNamespaceURI(const XMLCh* prefix) const {return fNode.lookupNamespaceURI(prefix); } 00580 void* DOMElementImpl::getFeature(const XMLCh* feature, const XMLCh* version) const {return fNode.getFeature(feature, version); } 00581 00582 00583 00584 bool DOMElementImpl::isEqualNode(const DOMNode* arg) const 00585 { 00586 if (isSameNode(arg)) { 00587 return true; 00588 } 00589 00590 if (!fNode.isEqualNode(arg)) { 00591 return false; 00592 } 00593 00594 bool hasAttrs = hasAttributes(); 00595 00596 if (hasAttrs != arg->hasAttributes()) { 00597 return false; 00598 } 00599 00600 if (hasAttrs) { 00601 DOMNamedNodeMap* map1 = getAttributes(); 00602 DOMNamedNodeMap* map2 = arg->getAttributes(); 00603 00604 XMLSize_t len = map1->getLength(); 00605 if (len != map2->getLength()) { 00606 return false; 00607 } 00608 for (XMLSize_t i = 0; i < len; i++) { 00609 DOMNode* n1 = map1->item(i); 00610 if (!n1->getLocalName()) { // DOM Level 1 Node 00611 DOMNode* n2 = map2->getNamedItem(n1->getNodeName()); 00612 if (!n2 || !n1->isEqualNode(n2)) { 00613 return false; 00614 } 00615 } 00616 else { 00617 DOMNode* n2 = map2->getNamedItemNS(n1->getNamespaceURI(), 00618 n1->getLocalName()); 00619 if (!n2 || !n1->isEqualNode(n2)) { 00620 return false; 00621 } 00622 } 00623 } 00624 } 00625 00626 return fParent.isEqualNode(arg); 00627 } 00628 00629 DOMNode* DOMElementImpl::rename(const XMLCh* namespaceURI, const XMLCh* name) 00630 { 00631 DOMDocumentImpl* doc = (DOMDocumentImpl*) fParent.fOwnerDocument; 00632 00633 if (!namespaceURI || !*namespaceURI) { 00634 fName = doc->getPooledString(name); 00635 fAttributes->reconcileDefaultAttributes(getDefaultAttributes()); 00636 00637 // and fire user data NODE_RENAMED event 00638 castToNodeImpl(this)->callUserDataHandlers(DOMUserDataHandler::NODE_RENAMED, this, this); 00639 00640 return this; 00641 } 00642 else { 00643 00644 // create a new ElementNS 00645 DOMElementNSImpl* newElem = (DOMElementNSImpl*)doc->createElementNS(namespaceURI, name); 00646 00647 // transfer the userData 00648 doc->transferUserData(castToNodeImpl(this), castToNodeImpl(newElem)); 00649 00650 // remove old node from parent if any 00651 DOMNode* parent = getParentNode(); 00652 DOMNode* nextSib = getNextSibling(); 00653 if (parent) { 00654 parent->removeChild(this); 00655 } 00656 00657 // move children to new node 00658 DOMNode* child = getFirstChild(); 00659 while (child) { 00660 removeChild(child); 00661 newElem->appendChild(child); 00662 child = getFirstChild(); 00663 } 00664 00665 // insert new node where old one was 00666 if (parent) { 00667 parent->insertBefore(newElem, nextSib); 00668 } 00669 00670 // move specified attributes to new node 00671 newElem->fAttributes->moveSpecifiedAttributes(fAttributes); 00672 00673 // and fire user data NODE_RENAMED event 00674 castToNodeImpl(newElem)->callUserDataHandlers(DOMUserDataHandler::NODE_RENAMED, this, newElem); 00675 00676 return newElem; 00677 } 00678 } 00679 00680 const DOMTypeInfo *DOMElementImpl::getSchemaTypeInfo() const 00681 { 00682 return &DOMTypeInfoImpl::g_DtdValidatedElement; 00683 } 00684 00685 // DOMElementTraversal 00686 DOMElement * DOMElementImpl::getFirstElementChild() const 00687 { 00688 DOMNode* n = getFirstChild(); 00689 while (n != NULL) { 00690 switch (n->getNodeType()) { 00691 case DOMNode::ELEMENT_NODE: 00692 return (DOMElement*) n; 00693 case DOMNode::ENTITY_REFERENCE_NODE: 00694 { 00695 DOMElement* e = getFirstElementChild(n); 00696 if (e != NULL) 00697 return e; 00698 } 00699 break; 00700 default: 00701 break; 00702 } 00703 n = n->getNextSibling(); 00704 } 00705 return NULL; 00706 } 00707 00708 DOMElement * DOMElementImpl::getLastElementChild() const 00709 { 00710 DOMNode* n = getLastChild(); 00711 while (n != NULL) { 00712 switch (n->getNodeType()) { 00713 case DOMNode::ELEMENT_NODE: 00714 return (DOMElement*) n; 00715 case DOMNode::ENTITY_REFERENCE_NODE: 00716 { 00717 DOMElement* e = getLastElementChild(n); 00718 if (e != NULL) 00719 return e; 00720 } 00721 break; 00722 default: 00723 break; 00724 } 00725 n = n->getPreviousSibling(); 00726 } 00727 return NULL; 00728 } 00729 00730 DOMElement * DOMElementImpl::getNextElementSibling() const 00731 { 00732 DOMNode* n = getNextLogicalSibling(this); 00733 while (n != NULL) { 00734 switch (n->getNodeType()) { 00735 case DOMNode::ELEMENT_NODE: 00736 return (DOMElement*) n; 00737 case DOMNode::ENTITY_REFERENCE_NODE: 00738 { 00739 DOMElement* e = getFirstElementChild(n); 00740 if (e != NULL) 00741 return e; 00742 } 00743 break; 00744 default: 00745 break; 00746 } 00747 n = getNextLogicalSibling(n); 00748 } 00749 return NULL; 00750 } 00751 00752 DOMElement * DOMElementImpl::getPreviousElementSibling() const 00753 { 00754 DOMNode* n = getPreviousLogicalSibling(this); 00755 while (n != NULL) { 00756 switch (n->getNodeType()) { 00757 case DOMNode::ELEMENT_NODE: 00758 return (DOMElement*) n; 00759 case DOMNode::ENTITY_REFERENCE_NODE: 00760 { 00761 DOMElement* e = getLastElementChild(n); 00762 if (e != NULL) 00763 return e; 00764 } 00765 break; 00766 default: 00767 break; 00768 } 00769 n = getPreviousLogicalSibling(n); 00770 } 00771 return NULL; 00772 } 00773 00774 XMLSize_t DOMElementImpl::getChildElementCount() const 00775 { 00776 XMLSize_t count = 0; 00777 DOMElement* child = getFirstElementChild(); 00778 while (child != NULL) { 00779 ++count; 00780 child = child->getNextElementSibling(); 00781 } 00782 return count; 00783 } 00784 00785 // Returns the first element node found from a 00786 // non-recursive in order traversal of the given node. 00787 DOMElement* DOMElementImpl::getFirstElementChild(const DOMNode* n) const 00788 { 00789 const DOMNode* top = n; 00790 while (n != NULL) { 00791 if (n->getNodeType() == DOMNode::ELEMENT_NODE) { 00792 return (DOMElement*) n; 00793 } 00794 DOMNode* next = n->getFirstChild(); 00795 while (next == NULL) { 00796 if (top == n) { 00797 break; 00798 } 00799 next = n->getNextSibling(); 00800 if (next == NULL) { 00801 n = n->getParentNode(); 00802 if (n == NULL || top == n) { 00803 return NULL; 00804 } 00805 } 00806 } 00807 n = next; 00808 } 00809 return NULL; 00810 } 00811 00812 // Returns the first element node found from a 00813 // non-recursive reverse order traversal of the given node. 00814 DOMElement* DOMElementImpl::getLastElementChild(const DOMNode* n) const 00815 { 00816 const DOMNode* top = n; 00817 while (n != NULL) { 00818 if (n->getNodeType() == DOMNode::ELEMENT_NODE) { 00819 return (DOMElement*) n; 00820 } 00821 DOMNode* next = n->getLastChild(); 00822 while (next == NULL) { 00823 if (top == n) { 00824 break; 00825 } 00826 next = n->getPreviousSibling(); 00827 if (next == NULL) { 00828 n = n->getParentNode(); 00829 if (n == NULL || top == n) { 00830 return NULL; 00831 } 00832 } 00833 } 00834 n = next; 00835 } 00836 return NULL; 00837 } 00838 00839 // Returns the next logical sibling with respect to the given node. 00840 DOMNode* DOMElementImpl::getNextLogicalSibling(const DOMNode* n) const 00841 { 00842 DOMNode* next = n->getNextSibling(); 00843 // If "n" has no following sibling and its parent is an entity reference node we 00844 // need to continue the search through the following siblings of the entity 00845 // reference as these are logically siblings of the given node. 00846 if (next == NULL) { 00847 DOMNode* parent = n->getParentNode(); 00848 while (parent != NULL && parent->getNodeType() == DOMNode::ENTITY_REFERENCE_NODE) { 00849 next = parent->getNextSibling(); 00850 if (next != NULL) { 00851 break; 00852 } 00853 parent = parent->getParentNode(); 00854 } 00855 } 00856 return next; 00857 } 00858 00859 // Returns the previous logical sibling with respect to the given node. 00860 DOMNode* DOMElementImpl::getPreviousLogicalSibling(const DOMNode* n) const 00861 { 00862 DOMNode* prev = n->getPreviousSibling(); 00863 // If "n" has no previous sibling and its parent is an entity reference node we 00864 // need to continue the search through the previous siblings of the entity 00865 // reference as these are logically siblings of the given node. 00866 if (prev == NULL) { 00867 DOMNode* parent = n->getParentNode(); 00868 while (parent != NULL && parent->getNodeType() == DOMNode::ENTITY_REFERENCE_NODE) { 00869 prev = parent->getPreviousSibling(); 00870 if (prev != NULL) { 00871 break; 00872 } 00873 parent = parent->getParentNode(); 00874 } 00875 } 00876 return prev; 00877 } 00878 00879 00880 XERCES_CPP_NAMESPACE_END