Java XML Node Compare compareLocations(Node node1, int offset1, Node node2, int offset2)

Here you can find the source of compareLocations(Node node1, int offset1, Node node2, int offset2)

Description

compare two nodes.

License

Open Source License

Parameter

Parameter Description
node1 a parameter
offset1 a parameter
node2 a parameter
offset2 a parameter

Return

less than zero if node1 < nodes2, 0 if node1 == node2, greater than zero if node1 > node2

Declaration

public static int compareLocations(Node node1, int offset1, Node node2, int offset2) 

Method Source Code

//package com.java2s;
/*/*from ww  w .  j  a  v a2s . c o  m*/
 * ? Copyright IBM Corp. 2012
 * 
 * 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.
 */

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class Main {
    /**
     * compare two nodes. Needed to write my own because of problems in the implementation
     * of the WST Range.compareBoundaryPoints();
     * 
     * @param node1
     * @param offset1
     * @param node2
     * @param offset2
     * @return less than zero if node1 < nodes2, 0 if node1 == node2, greater than zero if node1 > node2
     */
    public static int compareLocations(Node node1, int offset1, Node node2, int offset2) {

        if (node1 == node2) {
            return offset1 - offset2;
        }

        // need  to find a common parent of the two edit parts,
        // then compare the respective ancestors of that 
        // commons part. The ancestor that is first in the list
        // is considers less than the other.
        List parents1 = getParents(node1);
        List parents2 = getParents(node2);

        // insert the parts into the parents list
        parents1.add(0, node1);
        parents2.add(0, node2);

        // add effective nodes to the list
        if (node1.hasChildNodes()) {
            parents1.add(0, node1.getChildNodes().item(offset1));
        }

        if (node2.hasChildNodes()) {
            parents2.add(0, node2.getChildNodes().item(offset2));
        }

        Node commonParent = null;
        int cpIndex1 = 1; // index of common parent in parents1
        int cpIndex2 = 0; // index of common parent in parents2

        // find a common parent by searching parents2 for items
        // in parent1.
        // skip the first element, so we don't get
        // a part on the mark as the common parent.
        for (Iterator iter = parents1.listIterator(cpIndex1); iter.hasNext();) {
            Node node = (Node) iter.next();
            int index = parents2.indexOf(node);
            if (index > 0) { // don't allow the part at the mark to be a parent
                commonParent = node;
                cpIndex2 = index;
                break;
            }
            cpIndex1++;
        }

        // this can happen when the document is in flux.
        if (commonParent == null) {
            return -1;
        }

        // get the direct childs of the common parent and
        // compare their position in the flow.
        NodeList cpChildren = commonParent.getChildNodes();

        Node cpChild1 = (Node) parents1.get(cpIndex1 - 1); // child of common parent representing node1
        Node cpChild2 = (Node) parents2.get(cpIndex2 - 1); // child of common parent representing node2
        if (cpChild1 == cpChild2) {
            return offset1 - offset2;
        } else if (cpChild1 == null) { // cpChild1 is the last child
            return 1;
        } else if (cpChild2 == null) { // cpChild2 is the last child
            return -1;
        }

        int indexCpChild1 = getOffsetInParent(cpChild1);
        for (int i = (indexCpChild1 + 1); i < cpChildren.getLength(); i++) {
            if (cpChildren.item(i) == cpChild2) {
                return -1; // node1 comes before node2 (less than)
            }
        }

        // node2 not found in the above loop so it must have
        // come before node1 in the list. This means node1 is
        // greater than node2.
        return 1;
    }

    /**
     * 
     * @param node
     * @return a list of parent nodes
     */
    private static List getParents(Node node) {
        List list = new ArrayList();
        node = node.getParentNode();
        while (node != null) {
            list.add(node);
            node = node.getParentNode();
        }

        return list;
    }

    /**
     * Helper method to get the offset of a given node with respect to its
     * parent.
     * 
     * @param node -
     *            may not be null
     * @return int - zero-based offset of node in its container or -1 if the
     *         node as no container.
     */
    public static int getOffsetInParent(Node node) {
        Node parent = node.getParentNode();
        if (parent != null) {
            NodeList children = parent.getChildNodes();
            for (int i = 0; i < children.getLength(); i++) {
                Node child = (Node) children.item(i);
                if (child == node) {
                    return i;
                }
            }
            throw new IllegalStateException(); // how could the child not be
            // found?
        }

        return -1;
    }
}

Related

  1. areEqual(Node left, Node right)
  2. compare(Node n1, Node n2)
  3. compareNode(Node nQ, Node nN, Boolean considerLength, Map qvars)
  4. compareNodes(Node expected, Node actual)
  5. compareStringNode(Node node, String tag)
  6. compareTwoNodes(Node m, Node n)