Java examples for XML:XML Node
Implementation independent version of the XML Node.isEqualNode() method.
/**/*from w w w . j a v a2 s .co m*/ * Copyright 2012 Sven Ewald * * 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. */ //package com.java2s; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public class Main { /** * */ private static final Comparator<? super Node> ATTRIBUTE_NODE_COMPARATOR = new Comparator<Node>() { private int compareMaybeNull(final Comparable<Object> a, final Object b) { if (a == b) { return 0; } if (a == null) { return -1; } if (b == null) { return 1; } return a.compareTo(b); } @Override public int compare(final Node o1, final Node o2) { Comparable<Object>[] c1 = getNodeAttributes(o1); Comparable<Object>[] c2 = getNodeAttributes(o2); assert c1.length == c2.length; for (int i = 0; i < c1.length; ++i) { int result = compareMaybeNull(c1[i], c2[i]); if (result != 0) { return result; } } return 0; } }; /** * Implementation independent version of the Node.isEqualNode() method. Matches the same * algorithm as the nodeHashCode method. <br> * Two nodes are equal if and only if the following conditions are satisfied: * <ul> * <li>The two nodes are of the same type.</li> * <li>The following string attributes are equal: <code>nodeName</code>, <code>localName</code>, * <code>namespaceURI</code>, <code>prefix</code>, <code>nodeValue</code> . This is: they are * both <code>null</code>, or they have the same length and are character for character * identical.</li> * <li>The <code>attributes</code> <code>NamedNodeMaps</code> are equal. This is: they are both * <code>null</code>, or they have the same length and for each node that exists in one map * there is a node that exists in the other map and is equal, although not necessarily at the * same index.</li> * <li>The <code>childNodes</code> <code>NodeLists</code> are equal. This is: they are both * <code>null</code>, or they have the same length and contain equal nodes at the same index. * Note that normalization can affect equality; to avoid this, nodes should be normalized before * being compared.</li> * </ul> * <br> * For two <code>DocumentType</code> nodes to be equal, the following conditions must also be * satisfied: * <ul> * <li>The following string attributes are equal: <code>publicId</code>, <code>systemId</code>, * <code>internalSubset</code>.</li> * <li>The <code>entities</code> <code>NamedNodeMaps</code> are equal.</li> * <li>The <code>notations</code> <code>NamedNodeMaps</code> are equal.</li> * </ul> * * @param a * @param b * @return true if and only if the nodes are equal in the manner explained above */ public static boolean nodesAreEqual(final Node a, final Node b) { if (a == b) { return true; } if ((a == null) || (b == null)) { return false; } if (!Arrays.equals(getNodeAttributes(a), getNodeAttributes(b))) { return false; } if (!namedNodeMapsAreEqual(a.getAttributes(), b.getAttributes())) { return false; } if (!nodeListsAreEqual(a.getChildNodes(), b.getChildNodes())) { return false; } return true; } @SuppressWarnings("unchecked") private static Comparable<Object>[] getNodeAttributes(final Node node) { return new Comparable[] { Short.valueOf(node.getNodeType()), node.getNodeName(), node.getLocalName(), node.getNamespaceURI(), node.getPrefix(), node.getNodeValue() }; } /** * NamedNodeMaps (e.g. the attributes of a node) are equal if for each containing node an equal * node exists in the other map. * * @param a * @param b * @return */ private static boolean namedNodeMapsAreEqual(final NamedNodeMap a, final NamedNodeMap b) { if (a == b) { return true; } if ((a == null) || (b == null)) { return false; } if (a.getLength() != b.getLength()) { return false; } List<Node> listA = new ArrayList<Node>(a.getLength()); List<Node> listB = new ArrayList<Node>(a.getLength()); for (int i = 0; i < a.getLength(); ++i) { listA.add(a.item(i)); listB.add(b.item(i)); } Collections.sort(listA, ATTRIBUTE_NODE_COMPARATOR); Collections.sort(listB, ATTRIBUTE_NODE_COMPARATOR); for (Node n1 : listA) { if (!nodesAreEqual(n1, listB.remove(0))) { return false; } } return true; } /** * NodeLists are equal if and only if their size is equal and the containing nodes at the same * indexes are equal. * * @param a * @param b * @return */ private static boolean nodeListsAreEqual(final NodeList a, final NodeList b) { if (a == b) { return true; } if ((a == null) || (b == null)) { return false; } if (a.getLength() != b.getLength()) { return false; } for (int i = 0; i < a.getLength(); ++i) { if (!nodesAreEqual(a.item(i), b.item(i))) { return false; } } return true; } }