All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.crabshue.commons.xpath.XmlPathCalculator Maven / Gradle / Ivy

package com.crabshue.commons.xpath;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

/**
 * XML unique path computer.
 *
 * @author vinh
 */
public class XmlPathCalculator {

    private static Logger logger = LoggerFactory.getLogger(XmlPathCalculator.class);

    /**
     * Compute the unique XPath for a {@link Node}.
     *
     * @param node the node.
     * @return the unique XPath.
     */
    public static String computeUniquePath(Node node) {
        Validate.notNull(node);

        Node parent = node.getParentNode();
        if (parent == null && node instanceof Document) {
            return "";
        }
        final int nbPreviousSiblings = countPreviousSiblings(node);
        final int nbNextSiblings = countNextSiblings(node);
        if (nbPreviousSiblings == 0 && nbNextSiblings == 0) {
            return computeUniquePath(parent) + "/" + node.getNodeName();
        }

        final int nodeNumber = nbPreviousSiblings + 1;
        return computeUniquePath(parent) + "/" + node.getNodeName() + "[" + nodeNumber + "]";
    }

    static int countPreviousSiblings(Node node) {
        Validate.notNull(node);

        int cpt = 0;
        Node previousSibling = node.getPreviousSibling();
        while (previousSibling != null) {
            if (StringUtils.equals(previousSibling.getNodeName(), node.getNodeName())) {
                cpt++;
            }
            previousSibling = previousSibling.getPreviousSibling();
        }
        return cpt;
    }

    static int countNextSiblings(Node node) {
        Validate.notNull(node);

        int cpt = 0;
        Node nextSibling = node.getNextSibling();
        while (nextSibling != null) {
            if (StringUtils.equals(nextSibling.getNodeName(), node.getNodeName())) {
                cpt++;
            }
            nextSibling = nextSibling.getNextSibling();
        }
        return cpt;
    }
}






© 2015 - 2025 Weber Informatics LLC | Privacy Policy