domnodeimpl.cpp
来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 1,113 行 · 第 1/3 页
CPP
1,113 行
}void* DOMNodeImpl::getUserData(const XMLCh* key) const{ if (hasUserData()) return ((DOMDocumentImpl*)getOwnerDocument())->getUserData(this, key); return 0;}void DOMNodeImpl::callUserDataHandlers(DOMUserDataHandler::DOMOperationType operation, const DOMNode* src, const DOMNode* dst) const{ DOMDocumentImpl* doc=(DOMDocumentImpl*)getOwnerDocument(); if (doc) doc->callUserDataHandlers(this, operation, src, dst);}bool DOMNodeImpl::isSameNode(const DOMNode* other) const{ return (castToNode(this) == other);}bool DOMNodeImpl::isEqualNode(const DOMNode* arg) const{ if (!arg) return false; if (isSameNode(arg)) { return true; } DOMNode* thisNode = castToNode(this); if (arg->getNodeType() != thisNode->getNodeType()) { return false; } // the compareString will check null string as well if (!XMLString::equals(thisNode->getNodeName(), arg->getNodeName())) { return false; } if (!XMLString::equals(thisNode->getLocalName(),arg->getLocalName())) { return false; } if (!XMLString::equals(thisNode->getNamespaceURI(), arg->getNamespaceURI())) { return false; } if (!XMLString::equals(thisNode->getPrefix(), arg->getPrefix())) { return false; } if (!XMLString::equals(thisNode->getNodeValue(), arg->getNodeValue())) { return false; } if (!XMLString::equals(thisNode->getBaseURI(), arg->getBaseURI())) { return false; } return true;}const XMLCh* DOMNodeImpl::lookupNamespacePrefix(const XMLCh* namespaceURI, bool useDefault) const { // REVISIT: When Namespaces 1.1 comes out this may not be true // Prefix can't be bound to null namespace if (namespaceURI == 0) { return 0; } DOMNode *thisNode = castToNode(this); short type = thisNode->getNodeType(); switch (type) { case DOMNode::ELEMENT_NODE: { return lookupNamespacePrefix(namespaceURI, useDefault, (DOMElement*)thisNode); } case DOMNode::DOCUMENT_NODE:{ return ((DOMDocument*)thisNode)->getDocumentElement()->lookupNamespacePrefix(namespaceURI, useDefault); } case DOMNode::ENTITY_NODE : case DOMNode::NOTATION_NODE: case DOMNode::DOCUMENT_FRAGMENT_NODE: case DOMNode::DOCUMENT_TYPE_NODE: // type is unknown return 0; case DOMNode::ATTRIBUTE_NODE:{ if (fOwnerNode->getNodeType() == DOMNode::ELEMENT_NODE) { return fOwnerNode->lookupNamespacePrefix(namespaceURI, useDefault); } return 0; } default:{ DOMNode *ancestor = getElementAncestor(thisNode); if (ancestor != 0) { return ancestor->lookupNamespacePrefix(namespaceURI, useDefault); } return 0; } }}DOMNode* DOMNodeImpl::getElementAncestor (const DOMNode* currentNode) const { DOMNode* parent = currentNode->getParentNode(); if (parent != 0) { short type = parent->getNodeType(); if (type == DOMNode::ELEMENT_NODE) { return parent; } return getElementAncestor(parent); } return 0;}const XMLCh* DOMNodeImpl::lookupNamespacePrefix(const XMLCh* const namespaceURI, bool useDefault, DOMElement *el) const { DOMNode *thisNode = castToNode(this); const XMLCh* ns = thisNode->getNamespaceURI(); // REVISIT: if no prefix is available is it null or empty string, or // could be both? const XMLCh* prefix = thisNode->getPrefix(); if (ns != 0 && XMLString::equals(ns,namespaceURI)) { if (useDefault || prefix != 0) { const XMLCh* foundNamespace = el->lookupNamespaceURI(prefix); if (foundNamespace != 0 && XMLString::equals(foundNamespace, namespaceURI)) { return prefix; } } } if (thisNode->hasAttributes()) { DOMNamedNodeMap *nodeMap = thisNode->getAttributes(); if(nodeMap != 0) { int length = nodeMap->getLength(); for (int i = 0;i < length;i++) { DOMNode *attr = nodeMap->item(i); const XMLCh* attrPrefix = attr->getPrefix(); const XMLCh* value = attr->getNodeValue(); ns = attr->getNamespaceURI(); if (ns != 0 && XMLString::equals(ns, XMLUni::fgXMLNSURIName)) { // DOM Level 2 nodes if ((useDefault && XMLString::equals(attr->getNodeName(), XMLUni::fgXMLNSString)) || (attrPrefix != 0 && XMLString::equals(attrPrefix, XMLUni::fgXMLNSString)) && XMLString::equals(value, namespaceURI)) { const XMLCh* localname= attr->getLocalName(); const XMLCh* foundNamespace = el->lookupNamespaceURI(localname); if (foundNamespace != 0 && XMLString::equals(foundNamespace, namespaceURI)) { return localname; } } } } } } DOMNode *ancestor = getElementAncestor(thisNode); if (ancestor != 0) { return castToNodeImpl(ancestor)->lookupNamespacePrefix(namespaceURI, useDefault, el); } return 0;}const XMLCh* DOMNodeImpl::lookupNamespaceURI(const XMLCh* specifiedPrefix) const { DOMNode *thisNode = castToNode(this); short type = thisNode->getNodeType(); switch (type) { case DOMNode::ELEMENT_NODE : { const XMLCh* ns = thisNode->getNamespaceURI(); const XMLCh* prefix = thisNode->getPrefix(); if (ns != 0) { // REVISIT: is it possible that prefix is empty string? if (specifiedPrefix == 0 && prefix == specifiedPrefix) { // looking for default namespace return ns; } else if (prefix != 0 && XMLString::equals(prefix, specifiedPrefix)) { // non default namespace return ns; } } if (thisNode->hasAttributes()) { DOMNamedNodeMap *nodeMap = thisNode->getAttributes(); if(nodeMap != 0) { int length = nodeMap->getLength(); for (int i = 0;i < length;i++) { DOMNode *attr = nodeMap->item(i); const XMLCh *attrPrefix = attr->getPrefix(); const XMLCh *value = attr->getNodeValue(); ns = attr->getNamespaceURI(); if (ns != 0 && XMLString::equals(ns, XMLUni::fgXMLNSURIName)) { // at this point we are dealing with DOM Level 2 nodes only if (specifiedPrefix == 0 && XMLString::equals(attr->getNodeName(), XMLUni::fgXMLNSString)) { // default namespace return value; } else if (attrPrefix != 0 && XMLString::equals(attrPrefix, XMLUni::fgXMLNSString) && XMLString::equals(attr->getLocalName(), specifiedPrefix)) { // non default namespace return value; } } } } } DOMNode *ancestor = getElementAncestor(thisNode); if (ancestor != 0) { return ancestor->lookupNamespaceURI(specifiedPrefix); } return 0; } case DOMNode::DOCUMENT_NODE : { return((DOMDocument*)thisNode)->getDocumentElement()->lookupNamespaceURI(specifiedPrefix); } case DOMNode::ENTITY_NODE : case DOMNode::NOTATION_NODE: case DOMNode::DOCUMENT_FRAGMENT_NODE: case DOMNode::DOCUMENT_TYPE_NODE: // type is unknown return 0; case DOMNode::ATTRIBUTE_NODE:{ if (fOwnerNode->getNodeType() == DOMNode::ELEMENT_NODE) { return fOwnerNode->lookupNamespaceURI(specifiedPrefix); } return 0; } default:{ DOMNode *ancestor = getElementAncestor(castToNode(this)); if (ancestor != 0) { return ancestor->lookupNamespaceURI(specifiedPrefix); } return 0; } }}const XMLCh* DOMNodeImpl::getBaseURI() const{ DOMNode *thisNode = castToNode(this); DOMNode* parent = thisNode->getParentNode(); if (parent) return parent->getBaseURI(); else return 0;}short DOMNodeImpl::compareTreePosition(const DOMNode* other) const { // Questions of clarification for this method - to be answered by the // DOM WG. Current assumptions listed - LM // // 1. How do ENTITY nodes compare? // Current assumption: TREE_POSITION_DISCONNECTED, as ENTITY nodes // aren't really 'in the tree' // // 2. How do NOTATION nodes compare? // Current assumption: TREE_POSITION_DISCONNECTED, as NOTATION nodes // aren't really 'in the tree' // // 3. Are TREE_POSITION_ANCESTOR and TREE_POSITION_DESCENDANT // only relevant for nodes that are "part of the document tree"? // <outer> // <inner myattr="true"/> // </outer> // Is the element node "outer" considered an ancestor of "myattr"? // Current assumption: No. // // 4. How do children of ATTRIBUTE nodes compare (with eachother, or // with children of other attribute nodes with the same element) // Current assumption: Children of ATTRIBUTE nodes are treated as if // they are the attribute node itself, unless the 2 nodes // are both children of the same attribute. // // 5. How does an ENTITY_REFERENCE node compare with it's children? // Given the DOM, it should precede its children as an ancestor. // Given "document order", does it represent the same position? // Current assumption: An ENTITY_REFERENCE node is an ancestor of its // children. // // 6. How do children of a DocumentFragment compare? // Current assumption: If both nodes are part of the same document // fragment, there are compared as if they were part of a document. DOMNode* thisNode = castToNode(this); // If the nodes are the same... if (thisNode == other) return (DOMNode::TREE_POSITION_SAME_NODE | DOMNode::TREE_POSITION_EQUIVALENT); // If either node is of type ENTITY or NOTATION, compare as disconnected short thisType = thisNode->getNodeType(); short otherType = other->getNodeType(); // If either node is of type ENTITY or NOTATION, compare as disconnected if (thisType == DOMNode::ENTITY_NODE || thisType == DOMNode::NOTATION_NODE || otherType == DOMNode::ENTITY_NODE || otherType == DOMNode::NOTATION_NODE ) { return DOMNode::TREE_POSITION_DISCONNECTED; } //if this is a custom node, we don't really know what to do, just return //user should provide its own compareTreePosition logic, and shouldn't reach here if(thisType > 12) { return 0; } //if it is a custom node we must ask it for the order if(otherType > 12) { return reverseTreeOrderBitPattern(other->compareTreePosition(castToNode(this))); } // Find the ancestor of each node, and the distance each node is from // its ancestor. // During this traversal, look for ancestor/descendent relationships // between the 2 nodes in question. // We do this now, so that we get this info correct for attribute nodes // and their children. const DOMNode *node; const DOMNode *thisAncestor = castToNode(this); const DOMNode *otherAncestor = other; int thisDepth=0; int otherDepth=0; for (node = castToNode(this); node != 0; node = node->getParentNode()) { thisDepth +=1; if (node == other) // The other node is an ancestor of this one. return (DOMNode::TREE_POSITION_ANCESTOR | DOMNode::TREE_POSITION_PRECEDING); thisAncestor = node; } for (node=other; node != 0; node = node->getParentNode()) { otherDepth +=1; if (node == castToNode(this)) // The other node is a descendent of the reference node. return (DOMNode::TREE_POSITION_DESCENDANT | DOMNode::TREE_POSITION_FOLLOWING); otherAncestor = node; } const DOMNode *otherNode = other; short thisAncestorType = thisAncestor->getNodeType(); short otherAncestorType = otherAncestor->getNodeType(); // if the ancestor is an attribute, get owning element. // we are now interested in the owner to determine position. if (thisAncestorType == DOMNode::ATTRIBUTE_NODE) { thisNode = ((DOMAttrImpl *)thisAncestor)->getOwnerElement(); } if (otherAncestorType == DOMNode::ATTRIBUTE_NODE) { otherNode = ((DOMAttrImpl *)otherAncestor)->getOwnerElement(); } // Before proceeding, we should check if both ancestor nodes turned // out to be attributes for the same element
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?