Preceding sibling return empty node - xpath

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

Related

How to select an element that depends on another by 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')]]

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.

Listing job offers (schema.org’s JobPosting)

I have a page with list of jobs jobs offers and every job in list is link to page with job offer.
And I have a problem with Microdata, and my question is, which variant is better?
First variant:
<table itemscope itemtype="http://schema.org/JobPosting">
<tr>
<td itemprop="title" itemtype="http://schema.org/JobPosting" itemscope>job 1</td>
</tr>
<tr>
<td itemprop="title" itemtype="http://schema.org/JobPosting" itemscope>job 2</td>
</tr>
<tr>
<td itemprop="title" itemtype="http://schema.org/JobPosting" itemscope>job 3</td>
</tr>
</table>
Second variant:
<table>
<tr itemscope itemtype="http://schema.org/JobPosting">
<td itemprop="title"><a href..>job 1</a></td>
</tr>
<tr itemscope itemtype="http://schema.org/JobPosting">
<td itemprop="title"><a href..>job 2</a></td>
</tr>
<tr itemscope itemtype="http://schema.org/JobPosting">
<td itemprop="title"><a href..>job 3</a></td>
</tr>
</table>
Your first variant means: There is a JobPosting which has three titles. Each of these titles consists of another JobPosting.
Your second variant means: There are three JobPostings, each one has a title.
So you want to go with your second variant.
Note that you have an error on your current page. Instead of the example contained in your question, on your page you use itemprop="title" on the a element. But then the href value is the title, not the anchor text.
So instead of
<td>
<a itemprop="title" href="…" title="…">…</a>
</td>
<!-- the value of 'href' is the JobPosting title -->
you should use
<td itemprop="title">
<a class="list1" href="…" title="…">…</a>
</td>
<!-- the value of 'a' is the JobPosting title -->
And why not use the url property here?
<td itemprop="title">
<a itemprop="url" href="…" title="…">…</a>
</td>
The second one. The first one is describing a table as JobPosting which isn't a JobPosting.

Selenium webdriver using TestNG - Cannot locate correct Xpath of input field from label

here i want to fill the input field, but unable to access it by Xpath... Plz Help me out..
and the Code is below....
<table class="detailList" border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td class="labelCol">
<div id="div1">
<div class="pbSubsection">
<table class="detailList" border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td class="data2Col" colspan="2">
<span style="font-Size:12px;">
Process Name
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</td>
<td style="text-align:left;" class="data2Col">
<div id=div2">
<div class="pbSubsection">
<table class="detailList" border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td class="data2Col" colspan="2">
<div id="div3" class="requiredInput">
<div id="div4" class="requiredBlock"></div>
<input name="pName" style="width:50%;" type="text">
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</td>
</tr>
</tbody>
</table>
iam trying
WebElement ele = driver.findElement(By.xpath("//span[text()='Process Name']/preceding::td/div/input[#type='text']"));
ele.sendKeys("PM 001");
But here after preceding i know its wrong.. Plz Help me out with this.......
Here the name attribute value of input and div id's will change dynamically...
so iam trying to find by the label and preceding input tag...
Thanks in Advance
Your XPath is entirely wrong.
//span[normalize-space(text())='Process Name']/ancestor::tr/descendant::input
Is what you are after.
If the name of that input doesn't change, you can simply get it via:
driver.findElement(By.name("pName"));
Your XPath falls over at the first hurdle simply because that span has a lot of whitespacing around "Process Name", so use normalize-space to force it to strip the whitespaces from the text before comparing it.
You are also then falling over at the next stop, preceding ...you are the the span's level here, it's as deep as you can go, there's nothing 'preceding' it in the first place.
//span[normalize-space()='Process Name']//ancestor::tr//div//input[#type='text']

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