I have a table with 9 rows and 6 columns in my webpage. I want to search for a text \"MakeGoodDisabled-Programwise_09_44_38_461(n)\" and get the xpath of the cell. I have us
My java method to get absolute xpath:
public static String getXpath(WebElement element){
int n = element.findElements(By.xpath("./ancestor::*")).size();
String path = "";
WebElement current = element;
for(int i = n; i > 0; i--){
String tag = current.getTagName();
int lvl = current.findElements(By.xpath("./preceding-sibling::" + tag)).size() + 1;
path = String.format("/%s[%d]%s", tag, lvl, path);
current = current.findElement(By.xpath("./parent::*"));
}
return "/" + current.getTagName() + path;
}
and for relative xpath (this was first :) ):
public static String getXpath(WebElement self, WebElement ancestor){
int a = ancestor.findElements(By.xpath("./ancestor::*")).size();
int s = self.findElements(By.xpath("./ancestor::*")).size();
String path = "";
WebElement current = self;
for(int i = s - a; i > 0; i--){
String tag = current.getTagName();
int lvl = current.findElements(By.xpath("./preceding-sibling::" + tag)).size() + 1;
path = String.format("/%s[%d]%s", tag, lvl, path);
current = current.findElement(By.xpath("./parent::*"));
}
return path;
}
JavaScript fnction's to generate XPath
XPath/locator is a way of addressing an element by navigating through the Tree structure.
Absolute XPath (/): /html/body/div[5]/div[4]
WebElement XPath:
function WebElement_XPath(element) {
if (element.tagName == 'HTML') return '/html';
if (element===document.body) return '/html/body';
// calculate position among siblings
var position = 0;
// Gets all siblings of that element.
var siblings = element.parentNode.childNodes;
for (var i = 0; i < siblings.length; i++) {
var sibling = siblings[i];
// Check Siblink with our element if match then recursively call for its parent element.
if (sibling === element) return WebElement_XPath(element.parentNode)+'/'+element.tagName+'['+(position+1)+']';
// if it is a siblink & element-node then only increments position.
var type = sibling.nodeType;
if (type === 1 && sibling.tagName === element.tagName) position++;
}
}
MouseEvent XPath:
var eventXPath = '';
function MouseEvent_XPath(e) {
event = e.target || e.srcElement ||e.originalTarget;
for ( var xpathEle = ''; event && event.nodeType == 1; event = event.parentNode ) {
if ( event.tagName == 'HTML' || event.tagName == 'html' ) {
eventXPath = '//html'+xpathEle; break;
}
if ( event.tagName == 'BODY' || event.tagName == 'body' ) {
eventXPath = '//html/body'+xpathEle; break;
}
// calculate position among siblings
var position = 0;
// Gets all siblings of that event.
var siblings = event.parentNode.children;
for (var i = 0; i < siblings.length; i++) {
var sibling = siblings[i];
// Check Sibling with our event if match then recursively call for its parent event.
if (sibling === event) xpathEle = "/"+event.tagName+'['+(position+1)+']'+xpathEle;
// if it is a sibling with same tagName then only increments position.
if (sibling.tagName === event.tagName) position++;
}
}
}
Relative xpath (//): //div[@id=’social-media’]/ul/li[3]/a
//Element.TagName[@id="idvalue" and @class="classValue" and text()="innerHTML data"] OR you can use .(dot), . is an alias for text(), [.="innerHTML data"] if you know the content you are looking for is somewhere inside the specified tag, you can use this
Example run in console:
var xpath = "//div[@id='answer-32201731' and @data-answerid='32201731']";
var element = document.evaluate(xpath, window.document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue;
element.style.setProperty( 'outline', "3px solid blue","important");
I think their is not any special function available for getting the xpath of searched element. For this, First you need to find the element manually then get the xpath through getXpath functions.
Before iterating, use this class. Then, when you findXPATHIDFromWebElement
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
public class XPATHDriverWrapper {
Map xpathIDToWebElementMap = new LinkedHashMap();
Map webElementToXPATHIDMap = new LinkedHashMap();
public XPATHDriverWrapper(WebDriver driver){
WebElement htmlElement = driver.findElement(By.xpath("/html"));
iterateThroughChildren(htmlElement, "/html");
}
private void iterateThroughChildren(WebElement parentElement, String parentXPATH) {
Map siblingCountMap = new LinkedHashMap();
List childrenElements = parentElement.findElements(By.xpath(parentXPATH+"/*"));
for(int i=0;i<childrenElements.size(); i++) {
WebElement childElement = childrenElements.get(i);
String childTag = childElement.getTagName();
String childXPATH = constructXPATH(parentXPATH, siblingCountMap, childTag);
xpathIDToWebElementMap.put(childXPATH, childElement);
webElementToXPATHIDMap.put(childElement, childXPATH);
iterateThroughChildren(childElement, childXPATH);
// System.out.println("childXPATH:"+childXPATH);
}
}
public WebElement findWebElementFromXPATHID(String xpathID) {
return xpathIDToWebElementMap.get(xpathID);
}
public String findXPATHIDFromWebElement(WebElement webElement) {
return webElementToXPATHIDMap.get(webElement);
}
private String constructXPATH(String parentXPATH,
Map siblingCountMap, String childTag) {
Integer count = siblingCountMap.get(childTag);
if(count == null) {
count = 1;
} else {
count = count + 1;
}
siblingCountMap.put(childTag, count);
String childXPATH = parentXPATH + "/" + childTag + "[" + count + "]";
return childXPATH;
}
}
Another wrapper class to generate ids from Document is posted at: http://scottizu.wordpress.com/2014/05/12/generating-unique-ids-for-webelements-via-xpath/
Assuming you have an attribute on your element with the name "xpath" you could do the following:
WebElement yourElement = driver.findElement(By.xpath("//td[contains(text(),'MakeGoodDisabled-Programwise_09_44_38_461(n)')]");
String xpathAttributeValue = targetButton.getAttribute("xpath");
Though by the sounds of it you are trying to achieve something else here you have not shared with us yet. Do you want selenium to create an xpath for you? It can't.