Xpath - Selecting self or closest previous non-empty element - html

I have the following document:
<html>
<body>
<div>
<table>
<tr>
<td>390920000</td>
<td>A</td>
</tr>
<tr>
<td>390920000</td>
<td></td>
</tr>
<tr>
<td>3924100011</td>
<td>B</td>
</tr>
<tr>
<td>3924100011</td>
<td></td>
</tr>
<tr>
<td>3924100019</td>
<td></td>
</tr>
<tr>
<td>3924100019</td>
<td>C</td>
</tr>
</table>
</div>
</body>
</html>
What I would like is to use an xpath to select /html/body/div/table/tr/td[2], but for each empty element select the previous non-empty element instead. So instead of getting the values 'A','','B','','','C' I would like to get 'A','A','B','B','B','C'. Is this possible?
Btw, nevermind that this is an html and not an xml. I am using HtmlAgilityPack so I create ordinary xpath expressions to select html elements.

If XPath 3 is fine, the following should work:
//table/tr ! head((., reverse(preceding-sibling::*))[normalize-space(td[2]/text()) != ""])/td[2]

Related

XPath find element by position of different element

Example html:
<table>
<thead>
<tr>
<td class="foo"></td>
<td class="bar"></td>
<td class="buzz"></td>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>4</td>
<td>5</td>
<td>6</td>
</tr>
</tbody>
</table>
Problem
I have row position (//tbody/tr[X]) and header class (//thead//td[#class="XXX"])
I want to find table data cell using row and column
For example <td>5</td> can be located by //tbody/tr[2] and //thead//td[#class="bar"]
Pseudo-xpath:
//tbody/tr[2]/td[position() = //thead//td[#class="bar"]::position()]
I was tweaking with ancestor:: axis but it was dead end.
Any ideas how to write it properly?
Try to use this XPath to select required node:
//tbody/tr[2]/td[position() = count(//thead/tr/td[#class="bar"]/preceding-sibling::*) + 1]
Instead of position we're checking the count of preceding siblings + 1

How to xpath values in a dynamic table?

Could please someone help me to xpath values in a dynamic table.
I have the following HTML code and I need to select the values of the cells, as for example:
if a tr-cell contains the text "Values1" then select the first value (0) in td / third value (1) in td of this cell
I would be very thankful.
<table class="DynamicTable">
<tbody>
<tr>
<th>Details</th>
</tr>
<tr>
<td>0</td>
<td>Values1</td>
<td>1</td>
</tr>
<tr>
<td>4</td>
<td>Values2</td>
<td>2</td>
</tr>
<tr>
<td>1</td>
<td>Values6</td>
<td>0</td>
</tr>
</tbody>
</table>

About xpath in table java

I am trying to find the xpath of the button(its an input for real) from the name of the person in the corresponding line.
the right "connection" button from the name.
I have tried several xpath may saucun do not click the button I want.
It Clicks on the first button of the whole table each time
I tried this:
*d.driver.findElement(By.xpath("//tr/td[contains(text(), 'TOTO')]/following-sibling::td/input"));
and
*d.driver.findElement(By.xpath("//td[contains(text(), 'TOTO')]/following-sibling::td/input"));
and
*d.driver.findElement(By.xpath("//tr/td[contains(text(), 'TOTO')]/following-sibling::td/input[type='submit']"));
and
*d.driver.findElement(By.xpath("//tr/td[contains(text(),'TOTO')]//td[5]/input"));
I enclose the table.
Here is the HTML code :
<tr>
<td>FR1547</td>
<td>CAILLOUX</td>
<td>CHRISTIANE</td>
<td></td>
<td></td>
<td>UTILISATEUR</td>
<td><input value="connection" onclick="document.getElementById('hiddenCuid').value = 'FR1547'" type="submit"></td>
</tr>
<tr>
<td>US7784</td>
<td>TOTO</td>
<td>CHRISTINE</td>
<td></td>
<td></td>
<td>UTILISATEUR</td>
<td><input value="connection" onclick="document.getElementById('hiddenCuid').value = 'US7784'" type="submit"></td>
</tr>
Second button :
<tr>
<td>US4487</td>
<td>PONT</td>
<td>CHRISTIANE</td>
<td></td>
<td></td>
<td>UTILISATEUR, MANAGER</td>
<td><input value="connection" onclick="document.getElementById('hiddenCuid').value = 'US4487'" type="submit"></td>
</tr>
Try this xpath And check with Debugger, Whether its locates correctly:
//input[contains(#onclick,'US4487')]
try this xpath :
//td[text()='TOTO']/parent::tr/child::input

What regular expression can I use to find in an HTML document tables that only contain one row?

I'm searching through HTML documents and trying to find tables that only contain a single row. What regex can I use to do this? I've tried negative lookahead and can isolate a single row, but I don't see how to ensure that there's only a single <tr></tr> between <table></table> tags.
Here's the regex I'm working with now:
<table[\W].*?<tr[\W].*?<\/tr>.*(?!.*<tr[\W])<\/table>
This should NOT match the regex:
<html>
<body>
<table>
<tr>
<td>a</td>
</tr>
<tr>
<td>b</td>
</tr>
<tr>
<td>c</td>
</tr>
<tr>
<td>d</td>
</tr>
</table>
</body>
</html>
This SHOULD match the regex:
<html>
<body>
<table>
<tr>
<td>a</td>
</tr>
</table>
</body>
</html>
This should work: <table>(?>[^<]++|<(?!\/tr>))*<\/tr>(?>[^<]++|<(?!\/tr>))<\/table>
It is looking for only one instance of </tr> between <table> and </table>.
Details about it can be found here: Negative Lookaround Regex - Only one occurrence - Java
You could go for an approach with DOMDocument and xpath functions (namely count()). Assuming, you're using PHP (your question is tagged with PCRE):
<?php
$data = <<<DATA
<html>
<head/>
<body>
<table id="two_rows">
<tr><td>One column</td></tr>
<tr><td>Another column</td></tr>
</table>
<table id="one_row">
<tr><td>One column</td></tr>
</table>
</body>
</html>
DATA;
$dom = new DOMDocument();
$dom->loadHTML($data);
$xpath = new DOMXPath($dom);
$tables = $xpath->query("//table[count(tr) = 1]");
print_r($tables);
?>
See a demo on ideone.com.
Using .match() you can count the <tr>.
Try this:
str.match( /<tr.*?<\/tr>/g ).length

Selenium IDE: Why "Element X = Y not found" message, despite successful execution of test step?

Why does Selenium IDE give me the following error message, even when it successfully clicks on the UI button? I've tried all the available click, clickAndWait, Pause (pictured here), options I know of.
Exact Log:
[info] Executing: |click | class=button save | |
[error] Element class=button save not found
HTML:
</tr>
<tr>
<td>clickAndWait</td>
<td>id=login</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>link=Add</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>class=icon-capability</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>link=Capability</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>class=btn btn-primary</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>name=name</td>
<td>secondly</td>
</tr>
<tr>
<td>click</td>
<td>name=create</td>
<td></td>
</tr>
<tr>
<td>pause</td>
<td></td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>class=button save</td>
<td></td>
</tr>
</tbody></table>
</body>
</html>
my guess is the selector. You are looking for *[class='button save']
If the element you are selecting is:
// doesn't match
<button id="something" class="save button"></button>
// matches
<button id="something_else" class="button save"></button>
My guess is that something dynamically is happening. Try matching on something more unique than a class. If it has an ID attribute, use that. If it doesn't have that and it has a name attribute, use that.
If it doesn't have anything to match on BUT the class, then try using CSS.
css=button.button.save