Relative Xpath from list of WebElements
Solution 1
Yes, this is definitely possible. See this:
// Find the outer element.
WebElement outer = driver.findElement(By.anything("whatever"));
// This doesn't work, it searches the whole page for the XPath expression.
WebElement inner = outer.findElement(By.xpath("//some/nasty/xpath"));
// This works! It takes the outer element as root.
WebElement inner = outer.findElement(By.xpath(".//some/nasty/xpath"));
Therefore, if I understood your need well, your XPath expression needs to look like this:
By.xpath("(.//tbody)[" + j + "]//div[text()=\"" + collector + "\"])")
EDIT (Holy cow, that's a lot of HTML and only a small amount of it is actually needed :).)
Now that I caught what you're after, I think you don't need this approach at all. Try this instead:
WebElement row = driver.findElement(By.xpath("id('CollectorQoSPerformanceMetricsgrid')//div[contains(@class,'x-grid3-row x-unselectable-single') and .//u[text()='" + collector + "']]"));
Only the XPath expression:
id('CollectorQoSPerformanceMetricsgrid')
//div[contains(@class,'x-grid3-row x-unselectable-single')
and .//u[text()='" + collector + "'] ]
Taken apart:
FIND ELEM WITH ID = 'CollectorQoSPerformanceMetricsgrid'
id('CollectorQoSPerformanceMetricsgrid')
FIND ALL DIV ELEMS THAT CONTAIN 'x-grid3-row x-unselectable-single' IN @CLASS
//div[contains(@class,'x-grid3-row x-unselectable-single')
AND HAVE AN <U> DESCENDANT WITH TEXT EQUAL TO collector VARIABLE
and .//u[text()='" + collector + "'] ]
This finds you only the single row you need with a single command.
If you rather want to stick with your current solution, try:
String rowsXpath = "id('CollectorQoSPerformanceMetricsgrid')//div[contains(@class, 'x-grid3-row x-unselectable-single')]";
List<WebElement> rows = driver.findElements(By.xpath(rowsXpath));
boolean foundCollector = false;
for(WebElement row : rows) {
if(!row.findElements(By.xpath(".//u[text()='" + collector + "']")).isEmpty()) {
foundCollector = true;
break;
}
}
Solution 2
Nowhere I found row (tr tag) in this xpath then how it will get rows count.
String rowsXpath = "//div[@id=\"QosDashpardPanelBottom\"]//div[@id=\"CollectorQoSPerformanceMetricsgrid\"]//div[contains(@class, \"x-grid3-row x-unselectable-single\")]";
You need to construct xpath something like below to get row count in particular table
int rowCount=driver.findElements(By.xpath("//table[@class='x-grid3-row-table']/tbody/tr"))
Or else if you want to find all columns in that table with particular name
construct xpath like below
int columnCount=driver.findElements(By.xpath("//table[@class='x-grid3-row-table']/tbody//tr//td[@name='RequiredName']"))
so cal cheesehead
Avid test engineer with a development background
Updated on March 01, 2020Comments
-
so cal cheesehead over 4 years
Is it possible to use a relative xpath after I've gathered a list of WebElements? If so what's the best way to do it?
This is what I have:
List <WebElement> rows = driver.findElements(By.xpath(rowsXpath)); int j = 1; boolean foundCollector = false; for(WebElement e : rows) { String c = e.findElement(By.xpath("(//tbody)[" + j + "]//u[text()=\"" + collector + "\"])")).getText(); if(c.equals(collector)) { foundCollector = true; break; } ++j; }
the list rows contains individual rows with multiple columns and I'm trying to find the row which contains a particular name in a column. Within my for loop I was trying to use a relative xpath to look for an element, is this even possible? Or do I need to provide the whole xpath I used to find the rows with the additional xpath for the individual divs?
I'm not guaranteed the order of the columns which is why I have to do it this way.
This is the xpath I used to obtain the rows:
String rowsXpath = "//div[@id=\"QosDashpardPanelBottom\"]//div[@id=\"CollectorQoSPerformanceMetricsgrid\"]//div[contains(@class, \"x-grid3-row x-unselectable-single\")]";
Here's the HTML:
<body class=" ext-gecko ext-windows" onload="processLoaders();"> <script type="text/javascript"> <div id="topNavDiv" style="height: 90px"> <div id="bodyContentOuter" style="width: 1280px; height: 587px;"> <div id="bodyContentInner"> <script src="RLT/RLT.nocache.js" language="javascript" type="text/javascript"> <script defer="defer"> <script language="javascript" type="text/javascript"> <div id="rtcpMain" class=" x-component x-border-layout-ct" style="width: 1280px; height: 587px;"> <div id="rtcpMainWest" class=" x-panel x-component x-border-panel" style="left: 5px; top: 5px; width: 225px;"> <div id="x-auto-2" class=" x-tab-panel x-component x-border-panel" tabindex="0" hidefocus="true" style="left: 235px; top: 5px; width: 1040px;"> <div class="x-tab-panel-header x-unselectable" style="width: 1038px;" unselectable="on"> <div class="tone-rtcp-tabbed-content-panel" style="width: 1040px; height: 550px;"> <div id="x-auto-10" class=" x-component" style="overflow: auto; width: 1040px; height: 550px;"> <div id="QosDashboardPanel0" class=" x-panel x-component" style="width: 1040px;"> <div id="x-auto-13" class=" x-small-editor x-panel-header x-component x-hide-display" role="presentation"> <div id="rtcpDPBWrap" class="x-panel-bwrap" role="presentation" style="overflow: visible;"> <div class="x-panel-tbar x-panel-tbar-noheader" role="presentation" style="width: 1040px;"> <div id="rtcpDPBody" class="x-panel-body x-panel-body-noheader x-border-layout-ct" role="presentation" style="width: 1038px; height: 700px;"> <div id="QosDashboardPanelTop" class=" x-component x-border-panel x-border-layout-ct" style="left: 0px; top: 0px; width: 1038px; height: 400px;"> <div id="QosDashpardPanelBottom" class=" x-component x-border-panel x-border-layout-ct" style="left: 1px; top: 401px; width: 1036px; height: 298px;"> <div id="QosDashpardPanel_pqosChartsLC" class=" x-component x-border-panel x-border-layout-ct x-hide-display" style="left: 0px; top: 0px; width: 1036px; height: 400px;"> <div id="QosDashpardPanel_metricsTablesLC" class=" x-component x-border-panel x-border-layout-ct" style="left: 1px; top: 1px; width: 1034px; height: 296px;"> <div id="CollectorMetrics_toneletWrapper" class=" x-panel x-component x-border-panel" style="left: 1px; top: 1px; width: 330px;"> <div id="x-auto-99" class=" x-small-editor x-panel-header x-component x-hide-display" role="presentation"> <div class="x-panel-bwrap" role="presentation"> <div class="x-panel-body x-panel-body-noheader" role="presentation" style="width: 328px; height: 292px;"> <div id="CollectorMetrics" class=" x-panel x-component" style="width: 328px;"> <div id="x-auto-109" class=" x-small-editor x-panel-header x-component x-unselectable" role="presentation" unselectable="on"> <div class="x-panel-bwrap" role="presentation"> <div class="x-panel-body" role="presentation" style="width: 326px; height: 265px;"> <div id="CollectorQoSPerformanceMetricsgrid" class=" x-grid-panel x-component" style="position: relative; width: 326px; height: 265px;" tabindex="0" hidefocus="true" unselectable=""> <div class="x-grid3" role="presentation" style="width: 326px; height: 265px;"> <div class="x-grid3-viewport" role="presentation"> <div class="x-grid3-header" role="presentation"> <div class="x-grid3-scroller" role="presentation" style="width: 326px; height: 243px;"> <div class="x-grid3-body" role="presentation"> <div id="CollectorQoSPerformanceMetricsgrid_x-auto-633" class="x-grid3-row x-unselectable-single x-grid3-row-selected x-grid3-highlightrow " style="width:510px;"> <table class="x-grid3-row-table" cellspacing="0" cellpadding="0" border="0" style="width:510px;" role="presentation"> <tbody role="presentation"> <tr role="presentation"> <td id="x-auto-634" class="x-grid3-col x-grid3-cell x-grid3-td-name x-grid-cell-first " style="width:148px;" role="gridcell"> <div class="x-grid3-cell-inner x-grid3-col-name" unselectable="on"> <u>Lync</u> </div> </td> <td id="x-auto-635" class="x-grid3-col x-grid3-cell x-grid3-td-badCalls " style="width:53px;" role="gridcell"> <div class="x-grid3-cell-inner x-grid3-col-badCalls" unselectable="on">36</div> </td> <td id="x-auto-636" class="x-grid3-col x-grid3-cell x-grid3-td-totalCalls " style="width:58px;" role="gridcell"> <div class="x-grid3-cell-inner x-grid3-col-totalCalls" unselectable="on">120</div> </td> <td id="x-auto-637" class="x-grid3-col x-grid3-cell x-grid3-td-avgLatency " style="width:73px;" role="gridcell"> <div class="x-grid3-cell-inner x-grid3-col-avgLatency" unselectable="on">223</div> </td> <td id="x-auto-638" class="x-grid3-col x-grid3-cell x-grid3-td-avgLoss " style="width:53px;" role="gridcell"> <div class="x-grid3-cell-inner x-grid3-col-avgLoss" unselectable="on">0.80</div> </td> <td id="x-auto-639" class="x-grid3-col x-grid3-cell x-grid3-td-avgJitter " style="width:58px;" role="gridcell"> <div class="x-grid3-cell-inner x-grid3-col-avgJitter" unselectable="on">29</div> </td> <td id="x-auto-640" class="x-grid3-col x-grid3-cell x-grid3-td-avgMOS x-grid3-cell-last " style="width:53px;" role="gridcell"> <div class="x-grid3-cell-inner x-grid3-col-avgMOS" unselectable="on">3.86</div> </td> </tr> </tbody> </table> </div> <div id="CollectorQoSPerformanceMetricsgrid_x-auto-641" class="x-grid3-row x-unselectable-single " style="width:510px;"> <table class="x-grid3-row-table" cellspacing="0" cellpadding="0" border="0" style="width:510px;" role="presentation"> <tbody role="presentation"> <tr role="presentation"> <td id="x-auto-642" class="x-grid3-col x-grid3-cell x-grid3-td-name x-grid-cell-first " style="width:148px;" role="gridcell"> <div class="x-grid3-cell-inner x-grid3-col-name" unselectable="on"> <u>CUCM-Publisher</u> </div> </td> <td id="x-auto-643" class="x-grid3-col x-grid3-cell x-grid3-td-badCalls " style="width:53px;" role="gridcell"> <div class="x-grid3-cell-inner x-grid3-col-badCalls" unselectable="on">3</div> </td> <td id="x-auto-644" class="x-grid3-col x-grid3-cell x-grid3-td-totalCalls " style="width:58px;" role="gridcell"> <div class="x-grid3-cell-inner x-grid3-col-totalCalls" unselectable="on">52</div> </td> <td id="x-auto-645" class="x-grid3-col x-grid3-cell x-grid3-td-avgLatency " style="width:73px;" role="gridcell"> <div class="x-grid3-cell-inner x-grid3-col-avgLatency" unselectable="on">190</div> </td> <td id="x-auto-646" class="x-grid3-col x-grid3-cell x-grid3-td-avgLoss " style="width:53px;" role="gridcell"> <div class="x-grid3-cell-inner x-grid3-col-avgLoss" unselectable="on">0.79</div> </td> <td id="x-auto-647" class="x-grid3-col x-grid3-cell x-grid3-td-avgJitter " style="width:58px;" role="gridcell"> <div class="x-grid3-cell-inner x-grid3-col-avgJitter" unselectable="on">31</div> </td> <td id="x-auto-648" class="x-grid3-col x-grid3-cell x-grid3-td-avgMOS x-grid3-cell-last " style="width:53px;" role="gridcell"> <div class="x-grid3-cell-inner x-grid3-col-avgMOS" unselectable="on">3.98</div> </td> </tr> </tbody> </table> </div> </div>
-
so cal cheesehead over 11 yearsI tried it but it doesn't work, I get no results. I think I'm running into a problem with accessing individual rows. The full xpath if i try "//nasty/xpath/(.//tbody)[1]" on firebug for instance I don't get anything back.
-
Petr Janeček over 11 years@alexxp03 I use it on a daily basis, so the construct definitely works. You'll just have to come up with the right Xpath. If you can, post your HTML code in here, we'll work it out!
-
so cal cheesehead over 11 yearsI'd be glad to, this is driving me nuts. The html is quite large what's the best way to get it and post it?
-
Petr Janeček over 11 years@alexxp03 Copy it into notepad, remove everything that seems to be unrelated to your case. Then simply edit it into your question. If it's still too large, use pastebin.com or something. I'll be back in half an hour. You can also start a chat room for this and post here the link, if you want.
-
so cal cheesehead over 11 years0k i posted the html although the formatting is horrible i'm not sure how helpful it's going to be.
-
so cal cheesehead over 11 yearsI also put in the string i use to obtain the rows which would be my root element
-
so cal cheesehead over 11 yearsI posted more readable Html hopefully you can still take a look. thanks!
-
so cal cheesehead over 11 yearsmy question here was whether I could use relative paths after finding a whole. Assuming your rowCount xpath is correct, how would I access individual column values within the row reprinted by rowCount?
-
Petr Janeček over 11 years@alexxp03 Sorry about the delay :(. I have just updated my answer with a solution to your problem rather an answer to your question ;).
-
Vince Bowdren about 9 years@socalcheesehead Remember you always need the leading dot in a relative xpath i.e.
./some/more/xpath/
, not//some/more/xpath
or `/some/more/xpath