Java tutorial
//package com.java2s; /* * Copyright 2015 www.seleniumtests.com * 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 org.w3c.dom.Attr; import org.w3c.dom.Node; public class Main { /** * Gets parent XPath from the child XPath * <p/> * <br> XPath string is obtained by stripping all the characters from the last * <p/> * "/" character * * @param childXPath the child XPath */ public static String generateXPath(String childXPath) { return childXPath.substring(0, childXPath.lastIndexOf("/")); } /** * Generates XPath expression for the given node, relative to the Root of the Document */ public static String generateXPath(Node node, boolean ignoreWhitespace) { return generateXPath(node, ignoreWhitespace, false); } /** * Generates XPath expression with the option of the Node values and Node indexes are included * * @param node the Node whose XPath is to be found * @param ignoreWhitespace the flag to indicate if Whitespace will be ignored * @param noValues the flag to indicate if Node values will be included * @return the XPath string representation of the Node */ public static String generateXPath(Node node, boolean ignoreWhitespace, boolean noValues) { return generateXPath(node, ignoreWhitespace, noValues, false); } /** * Generates XPath expression with the option of the Node values appended * * @param node the Node whose XPath is to be found * @param ignoreWhitespace the flag to indicate if Whitespace will be ignored * @param includeValues the flag to indicate if Node values will be included * @param noIndex the flag to indicate if Node indexes are included * @return the XPath string representation of the Node */ public static String generateXPath(Node node, boolean ignoreWhitespace, boolean includeValues, boolean noIndex) { boolean noValues = !includeValues; if (node == null) return ""; Node parent = node.getParentNode(); int index = noIndex ? 0 : getXPathNodeIndex(node, ignoreWhitespace); String indexStr = ""; if (index > 0) indexStr = "[" + Integer.toString(index) + "]"; //printNode(node); //printNode(parent); if (node.getNodeType() == Node.DOCUMENT_NODE) { // return only the blank String, since all the other types are preceded with / return ""; } else if (node.getNodeType() == Node.TEXT_NODE) { return generateXPath(parent, ignoreWhitespace, noValues, noIndex) + (noValues ? node.getNodeValue() + indexStr : "/TEXT(" + node.getNodeValue() + ")" + indexStr); } else if (node.getNodeType() == Node.ELEMENT_NODE) { return generateXPath(parent, ignoreWhitespace, noValues, noIndex) + "/" + node.getNodeName() + indexStr; } else if (node.getNodeType() == Node.COMMENT_NODE) { return generateXPath(parent, ignoreWhitespace, noValues, noIndex) + (noValues ? node.getNodeValue() + indexStr : "/COMMENT(" + node.getNodeValue() + ")" + indexStr); } else if (node.getNodeType() == Node.ENTITY_REFERENCE_NODE) { return generateXPath(parent, ignoreWhitespace, noValues, noIndex) + (noValues ? node.getNodeValue() + indexStr : "/EntityReference(" + node.getNodeValue() + ")" + indexStr); } else if (node.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE) { return generateXPath(parent, ignoreWhitespace, noValues, noIndex) + (noValues ? node.getNodeValue() + indexStr : "/PI(" + node.getNodeValue() + ")" + indexStr); } else if (node.getNodeType() == Node.ATTRIBUTE_NODE) { return generateXPath(((Attr) node).getOwnerElement(), ignoreWhitespace, noValues, noIndex) + "/'@" + node.getNodeName() + (noValues ? "" : "=" + node.getNodeValue()) + "]"; } else if (node.getNodeType() == Node.DOCUMENT_TYPE_NODE) { return generateXPath(parent, ignoreWhitespace, noValues, noIndex) + (noValues ? node.getNodeValue() : "/DOCTYPE(" + node.getNodeName() + ")"); } else if (node.getNodeType() == Node.CDATA_SECTION_NODE) { return generateXPath(parent, ignoreWhitespace, noValues, noIndex) + (noValues ? node.getNodeValue() : "/CDATA(" + node.getNodeName() + ")"); } // Wont reach this far but just in case return ""; } /** * Generates XPath expression with the option of the Node values appended * * @param node the Node whose XPath is to be found * @param parentXPath the XPath of the parent Node * @param ignoreWhitespace the flag to indicate if Whitespace will be ignored * @param includeValues the flag to indicate if Node values will be included * @param noIndex the flag to indicate if Node indexes are included * @return the XPath string representation of the Node */ public static String generateXPath(Node node, String parentXPath, boolean ignoreWhitespace, boolean includeValues, boolean noIndex) { boolean noValues = !includeValues; if (node == null) return ""; Node parent = node.getParentNode(); int index = noIndex ? 0 : getXPathNodeIndex(node, ignoreWhitespace); String indexStr = ""; if (index > 0) indexStr = "[" + Integer.toString(index) + "]"; if (node.getNodeType() == Node.DOCUMENT_NODE) { // return only the blank String, since all the other types are preceded with / return parentXPath + ""; } else if (node.getNodeType() == Node.TEXT_NODE) { return parentXPath + (noValues ? "/" + node.getNodeValue() + indexStr : "/TEXT(" + node.getNodeValue() + ")" + indexStr); } else if (node.getNodeType() == Node.ELEMENT_NODE) { return parentXPath + "/" + node.getNodeName() + indexStr; } else if (node.getNodeType() == Node.COMMENT_NODE) { return parentXPath + (noValues ? "/" + node.getNodeValue() + indexStr : "/COMMENT(" + node.getNodeValue() + ")" + indexStr); } else if (node.getNodeType() == Node.ENTITY_REFERENCE_NODE) { return parentXPath + (noValues ? "/" + node.getNodeValue() + indexStr : "/EntityReference(" + node.getNodeValue() + ")" + indexStr); } else if (node.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE) { return parentXPath + (noValues ? "/" + node.getNodeValue() + indexStr : "/PI(" + node.getNodeValue() + ")" + indexStr); } else if (node.getNodeType() == Node.ATTRIBUTE_NODE) { return parentXPath + "/[@" + node.getNodeName() + (noValues ? "" : "=" + node.getNodeValue()) + "]"; } else if (node.getNodeType() == Node.DOCUMENT_TYPE_NODE) { return parentXPath + (noValues ? "/" + node.getNodeValue() : "/DOCTYPE(" + node.getNodeName() + ")"); } else if (node.getNodeType() == Node.CDATA_SECTION_NODE) { return parentXPath + (noValues ? "/" + node.getNodeValue() : "/CDATA(" + node.getNodeName() + ")"); } // Wont reach this far but just in case return ""; } /** * Gets Node Index value for the XPath expression<br> * <p/> * e.g. <root><a><b>ritesh</b><b>trivedi</b></a></root> calling * <p/> * getXPathNodeIndex for Node with value * <p/> * trivedi would return 2 */ public static int getXPathNodeIndex(Node node, boolean ignoreWhitespace) { int nodeIndex = 0; if (node == null) { return -1; //throw new IllegalArgumentException("Node argument for getXPathNodeIndex cannot be null"); } Node prevNode = node; //log("getXPathNodeIndex info next few lines"); //log("Current node:"); //printNode(node); while ((prevNode = prevNode.getPreviousSibling()) != null) { //log("previous node"); //printNode(prevNode); if (nodesEqual(node, prevNode, ignoreWhitespace)) nodeIndex++; } // If similar children are found, ONLY then increase // the nodeIndex by 1 since XPath exprn starts at 1 and not 0 if (nodeIndex > 0) nodeIndex++; if (nodeIndex == 0) { Node nextNode = node; boolean found = false; while (((nextNode = nextNode.getNextSibling()) != null) && (!found)) { //log("Next node"); //printNode(nextNode); if (nodesEqual(node, nextNode, ignoreWhitespace)) { nodeIndex++; found = true; } //node = prevNode; } } return nodeIndex; } /** * Checks if two Nodes are equal<br> * <p/> * Compares Nodes just by their Name, Type, Value and Namespace generically */ public static boolean nodesEqual(Node node1, Node node2, boolean ignoreWhitespace) { if ((node1 == null) || (node2 == null)) return false; /* if (node1.getNodeType() == node2.getNodeType() && (areNullorEqual(node1.getNodeValue(), node2.getNodeValue(), ignoreWhitespace, false)) && (areNullorEqual(node1.getLocalName(), node2.getLocalName(), ignoreWhitespace, false)) && (areNullorEqual(node1.getNamespaceURI(), node2.getNamespaceURI(), ignoreWhitespace, false)) && (areNullorEqual(node1.getNodeName(), node2.getNodeName(), ignoreWhitespace, false))) return true; */ if (areNonNullAndEqual(node1.getNamespaceURI(), node2.getNamespaceURI())) { if (node1.getNodeType() == node2.getNodeType() && (areNullorEqual(node1.getNodeValue(), node2.getNodeValue(), ignoreWhitespace, false)) && (areNullorEqual(node1.getLocalName(), node2.getLocalName(), ignoreWhitespace, false))) return true; } else if ((node1.getNamespaceURI() == null) && (node2.getNamespaceURI() == null)) { //System.out.println("===> Both Namespace URIs are null"); if ((node1.getNodeType() == node2.getNodeType()) && (areNullorEqual(node1.getNodeValue(), node2.getNodeValue(), ignoreWhitespace, false)) && (areNullorEqual(node1.getNodeName(), node2.getNodeName(), ignoreWhitespace, false))) return true; } return false; } /** * Checks if the input Objects are Non NULL and Equal */ public static boolean areNonNullAndEqual(Object obj1, Object obj2) { if ((obj1 == null) || (obj2 == null)) return false; return obj1.equals(obj2); } /** * Checks if both the Object arguments are equal (including if they are null) */ public static boolean areNullorEqual(Object obj1, Object obj2, boolean ignoreWhitespace, boolean ignoreCase) { // if both are null, they are equal if ((obj1 == null) && (obj2 == null)) return true; // if either one of them is null, they are not equal if ((obj1 == null) || (obj2 == null)) return false; // if they are String type if ((obj1 instanceof String) && (obj2 instanceof String)) { if (ignoreWhitespace) { if (ignoreCase) return ((String) obj1).trim().equalsIgnoreCase(((String) obj2).trim()); else return ((String) obj1).trim().equals(((String) obj2).trim()); } else { if (ignoreCase) return ((String) obj1).equalsIgnoreCase((String) obj2); else return obj1.equals(obj2); } } return (obj1.equals(obj2)); } }