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