/** * Adds a node using its nodeName attribute. As the nodeName attribute is used to derive the name * which the node must be stored under, multiple nodes of certain types (those that have a * "special" string value) cannot be stored as the names would clash. This is seen as preferable * to allowing nodes to be aliased. * * @see mf.org.w3c.dom.NamedNodeMap#setNamedItem * @return If the new Node replaces an existing node the replaced Node is returned, otherwise null * is returned. * @param arg A node to store in a named node map. The node will later be accessible using the * value of the namespaceURI and localName attribute of the node. If a node with those * namespace URI and local name is already present in the map, it is replaced by the new one. * @exception mf.org.w3c.dom.DOMException The exception description. */ public Node setNamedItem(Node arg) throws DOMException { CoreDocumentImpl ownerDocument = ownerNode.ownerDocument(); if (ownerDocument.errorChecking) { if (isReadOnly()) { String msg = DOMMessageFormatter.formatMessage( DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null); throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, msg); } if (arg.getOwnerDocument() != ownerDocument) { String msg = DOMMessageFormatter.formatMessage( DOMMessageFormatter.DOM_DOMAIN, "WRONG_DOCUMENT_ERR", null); throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, msg); } } int i = findNamePoint(arg.getNodeName(), 0); NodeImpl previous = null; if (i >= 0) { previous = (NodeImpl) nodes.get(i); nodes.set(i, arg); } else { i = -1 - i; // Insert point (may be end of list) if (null == nodes) { nodes = new ArrayList(5); } nodes.add(i, arg); } return previous; } // setNamedItem(Node):Node
protected int addItem(Node arg) { int i = findNamePoint(arg.getNamespaceURI(), arg.getLocalName()); if (i >= 0) { nodes.set(i, arg); } else { // If we can't find by namespaceURI, localName, then we find by // nodeName so we know where to insert. i = findNamePoint(arg.getNodeName(), 0); if (i >= 0) { nodes.add(i, arg); } else { i = -1 - i; // Insert point (may be end of list) if (null == nodes) { nodes = new ArrayList(5); } nodes.add(i, arg); } } return i; }
/** * Iterative tree-walker. When you have a Parent link, there's often no need to resort to * recursion. NOTE THAT only Element nodes are matched since we're specifically supporting * getElementsByTagName(). */ protected Node nextMatchingElementAfter(Node current) { Node next; while (current != null) { // Look down to first child. if (current.hasChildNodes()) { current = (current.getFirstChild()); } // Look right to sibling (but not from root!) else if (current != rootNode && null != (next = current.getNextSibling())) { current = next; } // Look up and right (but not past root!) else { next = null; for (; current != rootNode; // Stop when we return to starting point current = current.getParentNode()) { next = current.getNextSibling(); if (next != null) break; } current = next; } // Have we found an Element with the right tagName? // ("*" matches anything.) if (current != rootNode && current != null && current.getNodeType() == Node.ELEMENT_NODE) { String name = ((ElementImpl) current).getAttribute("name"); if (name.equals("*") || name.equals(tagName)) return current; } // Otherwise continue walking the tree } // Fell out of tree-walk; no more instances found return null; } // nextMatchingElementAfter(int):Node