How to select an element that depends on another by XPath - xpath

I need to build an xpath that returns my element only if dependency is present on the screen.
I'm currently filtering my element using the following snippet:
//div[contains(text(), 'my element')]
...
<div>
<table>
<tbody>
<tr>
<td>
<a>dependency</a>
</td>
</tr>
</tbody>
</table>
</div>
<div>
<div>my element</div>
</div>

//div[contains(text(), 'my element')][//a[contains(text(), 'dependency')]]

Related

Thymeleaf - Loop values into textarea

I've been stack with a problem in Thymeleaf, that is, looping values into a textarea. My controller provides me with a list/collection via the model binding:
model.addAttribute("response", getDefectMessage.getMessage());
getDefectMessage.getMessage() returns the following (please see image below), in which I only need description in this case.
In my HTML, I am able to display the index and count of the provided data retrieved from the model (please see sample code below).
<tbody>
<tr th:each="res, stat : *{response}">
<td th:text="${stat.count}" />
<td>
<textarea type="text" th:text="${res[__${stat.index}__].description}"></textarea>
</td>
</tr>
</tbody>
Having said that, I get a SpringEL expression exception when rendering (please see image below).
Exception evaluating SpringEL expression: "res[0].description" (defect_details:24)
Been a newbie in Thymeleaf, may I please get assistance in how I can go about displaying values from a list into a textarea. (Thanks in advance).
res represents a DefectDto. So you access it fields like res.defectDescription
<tbody>
<tr th:each="res, stat : *{response}">
<td th:text="${stat.count}" />
<td>
<textarea type="text" th:text="${res.defectDescription}">
</textarea>
</td>
</tr>
</tbody>
Or if DefectDto has a method getDescription() then you can do
<tbody>
<tr th:each="res, stat : *{response}">
<td th:text="${stat.count}" />
<td>
<textarea type="text" th:text="${res.description}">
</textarea>
</td>
</tr>
</tbody>

how to get table rows which is nested in other tables using xpath in scrapy spiders

How to get the table rows which is nested in other tables and form tag.
I tried few codes but doesn't seem to work.
I have used the below python code but not able to get anything
def parse(self, response):
t = response.xpath('//table[#class="DataGrid"]/tbody/tr')
for tr_obj in enumerate(t):
print(tr_obj.xpath('td[1]/text()').extract_first())
Below is html code and in this I need to get table which has the class name as gridTable
<html>
<body>
<table></table>
<table>
<tbody>
<tr>
<td>
<span></span>
<script></script>
<form>
<table class="dPage1">
<tbody>
<tr></tr>
<tr>
<td>
<table>
<tbody>
<tr>
<td>
<table class="gridTable">
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</form>
</td>
</tr>
</tbody>
</table>
</body>
</html>
Solution
for tr_obj in enumerate(response.xpath('//table[#class="DataGrid"]/tr')):
print(tr_obj.xpath('td[1]/text()').extract_first())
You can choose which tags to follow in xpath by specifying the tag in brackets.
For your example it would be:
//table[#class="gridTable"]/...
It is recommended that you must not use tbody in your XPath statements in the scrapy documentation.
So try without them and/or try to circumvent them by using /*/ or //.
Try something like:
def parse(self, response):
# Get a Selector list for all rows
sel_rows = response.xpath('//table[#class="DataGrid"]/tr')
# loop over row selectors ...
for sel_row in sel_rows:
print(sel_row.xpath('td[1]/text()').extract_first())

Is it possible to use a xpath within a xpath?

I have a table that looks like this:
<table>
<thead>
<tr>
<th data-th-key="col1"> <span> Foo </span> </th>
<th data-th-key="col2"> <span> Bar </span> </th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div>
<input data-model-key="col1">
</div>
</td>
<td>
<div>
<input data-model-key="col2">
</div>
</td>
</tr>
</tbody>
</table>
To find the right input element I have to know the data-th-key from the table head. Is there any way to use the first xpath inside the second one?
Xpath one:
//table//thead//span[translate(normalize-space(.),'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='foo']/parent::th/#data-th-key"
Xpath two:
//table//tbody//tr//td//div//input[#data-model-key='col1']
So I want to replace the col1 value in the second one with Xpath one.
You can write an expression like
//table//tbody//tr//td//div//input[#data-model-key = //table//thead//span[translate(normalize-space(.),'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='foo']/parent::th/#data-th-key]
yes, that is possible and meaningful and selects the input (or the inputs) whose data-model-key is equal to that data-th-key attribute.

Preceding sibling return empty node

In this example i have this code:
<table class="basicinfo" cellspacing="0">
<tr class="header">
<td colspan="3">
<div>
<h2 class="prod_card">Basic info</h2>
</div>
</td>
</tr>
<tr class="row2 item">
<td class="cell0">
<div>
Year
</div>
</td>
<td class="cell1">
<div>
2005
</div>
</td>
</tr>
<tr class="row3 item alt">
<td class="cell0">
<div>
Extra
</div>
</td>
<td class="cell1">
<div>
-
</div>
</td>
</tr>
</table>
Now, i want to get (for example) the year. I'm trying to get the next div content after the div with Year content.
I'm using this xpath without success:
//div[preceding-sibling::div = 'Year']
And anyone knows a good website to start learning xpath? Thanks in advance!
Following XPath
//div[parent::td/preceding-sibling::td//div[normalize-space()= 'Year']]
has the result
<div>2005</div>
Your XPath didn't work because the div you are looking for has not a div element as preceding-sibling but a td as parent. The preceding-sibling::td of this td contains a div which has the text "Year" - td//div. Using normalize-space() returns the text of this div without any spaces which can be necessary when checking for equality.
For reference: normalize-space(), and as you asked for good resources - I don't want to recommend anything special, but you should have a look at the resources mentioned at the info given on stackoverflow here: https://stackoverflow.com/tags/xpath/info (if not already done) and, for XPath axes, this is a good visualization: http://www.xmlplease.com/axis

how to determine xpaths for ajax element

I need to detemine xpath for element mainForm:queryConfigure:fetchReport.
<span id="mainForm:queryConfigure:j_id18">
<table id="mainForm:queryConfigure:j_id19"
class="showReportTable" align="center">
<tbody>
<tr>
<td>
<input id="mainForm:queryConfigure:fetchReport" type="image"
src="images/show_report.gif" name="mainForm:queryConfigure:fetchReport"/>
</td>
</tr>
</tbody>
</table>
</span>
I tried
selenium.click("//input[#id='mainForm:queryConfigure:fetchReport'][#type='image'][#src='images/show_report.gif']");
and
selenium.click("//input[#id='mainForm:queryConfigure:fetchReport']");
One more case:
<div class="tabUnselectedText" align="center">
Notifications
</div>
Id and name attribute values are acceptable locators for method click. See locating elements in the documentation.
selenium.click('mainForm:queryConfigure:fetchReport');

Resources