I have an HTML file that contains many tables, but I want to access a specific table from the file (not all tables).
So how can I do that?
Code is look something like below and all tables are without ids
`<table border=1>
<tr><td>VI not loadable</td><td>0</td></tr>
<tr><td>Test not loadable</td><td>0</td></tr>
<tr><td>Test not runnable</td><td>0</td></tr>
<tr><td>Test error out</td><td>0</td></tr>
</table>`
every table should have an Id or something that could be Identified from the others, if so you can get it via jquery. for example :
<table class="table table-striped" id="tbl1">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<tr>
<td>John</td>
<td>Doe</td>
<td>john#example.com</td>
</tr>
<tr>
<td>Mary</td>
<td>Moe</td>
<td>mary#example.com</td>
</tr>
<tr>
<td>July</td>
<td>Dooley</td>
<td>july#example.com</td>
</tr>
</tbody>
and get it like this:
var table = $('#tbl1').html();
if not you can find it by its priority in the file. for example you can access to 2nd table like this :
var table = $('table:nth-child(2)')
or in C# maybe this would help:
HtmlNode table = doc.DocumentNode.SelectSingleNode("//table[1]")
foreach (var cell in table.SelectNodes(".//tr/td"))
{
string someVariable = cell.InnerText
}
Related
I have a table like this:
<table border="0" cellpadding="0" cellspacing="0" id="table2">
<tr>
<th>Name
</th>
<th>Age
</th>
</tr>
<tr>
<td>Mario
</td>
<th>Age: 78
</td>
</tr>
<tr>
<td>Jane
</td>
<td>Age: 67
</td>
</tr>
<tr>
<td>James
</td>
<th>Age: 92
</td>
</tr>
</table>
I want to get the last td from all rows using Html Agility Pack.
Here is my C# code so far:
await page.GoToAsync(NumOfSaleItems, new NavigationOptions
{
WaitUntil = new WaitUntilNavigation[] { WaitUntilNavigation.DOMContentLoaded }
});
var html4 = page.GetContentAsync().GetAwaiter().GetResult();
var htmlDoc4 = new HtmlDocument();
htmlDoc4.LoadHtml(html4);
var SelectTable = htmlDoc4.DocumentNode.SelectNodes("/html/body/div[2]/div/div/div/table[2]/tbody/tr/td[1]/div[3]/div[2]/div/table[2]/tbody/tr/td[4]");
if (SelectTable.Count == 0)
{
continue;
}
else
{
foreach (HtmlNode row in SelectTable)//
{
string value = row.InnerText;
value = value.ToString();
var firstSpaceIndex = value.IndexOf(" ");
var firstString = value.Substring(0, firstSpaceIndex);
LastSellingDates.Add(firstString);
}
}
How can I get only the last column of the table?
I think the XPath you want is: //table[#id='table2']//tr/td[last()].
//table[#id='table2'] finds the table by ID anywhere in the document. This is preferable to a long brittle path from the root, since a table ID is less likely to change than the rest of the HTML structure.
//tr gets the descendent rows in the table. I'm using two slashes in case there might be an intervening <tbody> element in the actual HTML.
/td[last()] gets the last <td> in each row.
From there you just need to select the InnerText of each <td>.
var tds = htmlDoc.DocumentNode.SelectNodes("//table[#id='table2']//tr/td[last()]");
var values = tds?.Select(td => td.InnerText).ToList() ?? new List<string>();
Working demo here: https://dotnetfiddle.net/7I8yk1
I trying to change value of a particular cell in a table, but i am getting an error, can anyone see what the problem is please :
Test WebTable.IWebTableTests.testIWebTableTests failed: System.NullReferenceException : Object reference not set to an instance of an object.
WebTableTests.cs(37,0): at WebTable.IWebTableTests.testIWebTableTests()
<div class="cart-info">
<table border="1">
<thead>
<tr>
<td class="name">Product Name</td>
<td class="model">Model</td>
<td class="quantity">Quantity</td>
<td class="price">Unit Price</td>
<td class="total">Total</td>
</tr>
</thead>
<tbody>
</table>
</div>
and:
IWebElement table = driver.FindElement(By.CssSelector(".cart-info>table"));
ReadOnlyCollection<IWebElement> allRows = table.FindElements(By.TagName("tr"));
ReadOnlyCollection<IWebElement> allCols = table.FindElements(By.TagName("td"));
//Verify that it has three rows
Assert.AreEqual(3, allRows.Count);
//Verify that it has six columns
Assert.AreEqual(5, allCols.Count);
//Verify that specified value exists in second cell of third row
Assert.AreEqual("iPhone", allRows[3].FindElements(By.TagName("td"))[1].Text);
//Get in cell editor and enter some value
string cellValue = allRows[3].FindElements(By.TagName("td"))[3].Text;
IWebElement cellEdit = allRows[3].FindElements(By.TagName("td"))[3];
cellEdit.Clear();
cellEdit.SendKeys("2");
string aftercellValue = allRows[3].FindElements(By.TagName("td"))[3].Text;
I want to fetch all rows having a specific word/string in its.. and store it in array
I have a string as below
<tr>
<td>Total</td>
<td>123</td>
<td>567</td>
</tr>
<tr>
<td>ABC</td>
<td>123</td>
<td>567</td>
</tr>
<tr>
<td>XYZ</td>
<td>123</td>
<td>567</td>
</tr>
<tr>
<td>Total</td>
<td>7676</td>
<td>8767</td>
</tr>
I want to fetch a row having the string Total and the value of should store in array
So output should
<tr>
<td>Total</td>
<td>123</td>
<td>567</td>
</tr>
<tr>
<td>Total</td>
<td>7676</td>
<td>8767</td>
</tr>
what should be the regular expression to fetch a row with a string "Total"
To build arrays for each table row that has a cell with the word "Total", you could use this regex:
(?<=<tr>\s*<td>Total</td>)(\s*<td>\d+</td>)+(?=\s*</tr>)
Which would give you the following 2 matches:
<td>123</td>
<td>567</td>
and
<td>7676</td>
<td>8767</td>
On these matches you could then split with this regex to get arrays in return:
\D+
IN JQUERY UR SOLUTION WILL--->
var tbl = $('#tblId')
var array = [];
$('tr td' ,tbl).each(function(){
var htmlstring = (this).innerHTML;
if(htmlstring == 'Total')
{
if((this).innerHTML == 'Total')
{
$('td', this.parentNode).each(function(){
array.push(this);
});
}
}
});
alert(array);
http://jsfiddle.net/gXGj6/13/
Good solution using jQuery:
http://jsfiddle.net/robfarmer/KaGBL/2/
HTML:
Source
<table id="source">
<tr>
<td>Total</td>
<td>123</td>
<td>567</td>
</tr>
<tr>
<td>ABC</td>
<td>123</td>
<td>567</td>
</tr>
<tr>
<td>XYZ</td>
<td>123</td>
<td>567</td>
</tr>
<tr>
<td>Total</td>
<td>7676</td>
<td>8767</td>
</tr>
</table>
Results
<table id="results"></table>
Array Results:
<ul id="arrayResults"/>
Javascript
$(document).ready(function() {
$("#source tr td:contains('Total')").closest("tr").clone().appendTo("#results");
var cells = [];
$("#source tr td:contains('Total')").closest("tr")
.children("td").not(":contains('Total')").each(function(index, element) {
cells.push($(element).text());
});
$(cells).each(function(index, element) {
$("#arrayResults").append($("<li>").text(element));
});
});
I have something like this:
<table id="tableId" runat="server">
<thead>
<tr>
<th>Example thead1</th>
<th>Example thead2</th>
</tr>
</thead>
<tbody id="tb0">
<tr>
<td>Example 1</td>
<td>Something</td>
</tr>
</tbody>
<tbody id="tb1">
<tr>
<td>Example 2</td>
<td>Something</td></tr>
</tbody>
<tbody id="tb2">
<tr>
<td>Example 3</td>
<td>Something</td>
</tr>
</tbody>
</table>
I use multiple "tbody" with different IDs so I can delete it or create it anytime I want.
What I'd like to do is getting each row from multiple "tbody" from the table "tableId".
In C#, if I use the command "tableId.Rows[0].Cells[0].InnerHtml", I get the result: "Example thead1".
But if I use "tableId.Rows[3].Cells[0].InnerHtml", I can't get the "Example 3" as available in table row, instead of it I get an error which says that row doesn't exist or it's out of index.
I have tested the your code. and found that tableId.Rows[3].Cells[0].InnerHtml will give always Example 3 ..that's is correct as per your aspx markup code.
i think you have place row index incorrect i.e. something like below
tableId.Rows[4].Cells[0].InnerHtml which not exist in your table structure.
that's why you get error of Specified argument was out of the range of valid values.Parameter name: index
Hope this will helps you...happy coding...
Make the tbody elements server controls.
<tbody id="tb2" runat="server">
<tr>
<td>Example 3</td>
<td>Something</td>
</tr>
</tbody>
Then toggle the visibility as you need:
tb2.Visible = true / false;
As per comment:
Probably the designer doesn't create a reference to tb1, tb2, tb3 controls because they are inner controls of tableId.
If so:
var tb2 = tableId.FindControl("tb2");
tb2.Visible = ...
You could use JQuery, something like this....
$('tbody', '#tableid');
But I guess depends on what you want to do with them, and where
JQuery docs:
Selectors: http://api.jquery.com/category/selectors/
Traversing: http://api.jquery.com/category/traversing/
Im trying to download a page contain a table like this
<table id="content-table">
<tbody>
<tr>
<th id="name">Name</th>
<th id="link">link</th>
</tr>
<tr class="tt_row">
<td class="ttr_name">
<a title="name_of_the_movie" href="#"><b>name_of_the_movie</b></a>
<br>
<span class="pre">message</span>
</td>
<td class="td_dl">
<img alt="Download" src="#">
</td>
</tr>
<tr class="tt_row"> .... </tr>
<tr class="tt_row"> .... </tr>
</tbody>
</table>
i want to extract the name_of_the_movie from td class="ttr_name" and download link from td class="td_dl"
this is the code i used to loop through table rows
HtmlAgilityPack.HtmlDocument hDocument = new HtmlAgilityPack.HtmlDocument();
hDocument.LoadHtml(htmlSource);
HtmlNode table = hDocument.DocumentNode.SelectSingleNode("//table");
foreach (var row in table.SelectNodes("//tr"))
{
HtmlNode nameNode = row.SelectSingleNode("td[0]");
HtmlNode linkNode = row.SelectSingleNode("td[1]");
}
currently i have no idea how to check the nameNode and linkNode and extract data inside it
any help would be appreciated
Regards
I can't test it right now, but it should be something among the lines of :
string name= namenode.Element("a").Element("b").InnerText;
string url= linknode.Element("a").GetAttributeValue("href","unknown");
nameNode.Attributes["title"]
linkNode.Attributes["href"]
presuming you are getting the correct Nodes.
public const string UrlExtractor = #"(?: href\s*=)(?:[\s""']*)(?!#|mailto|location.|javascript|.*css|.*this\.)(?<url>.*?)(?:[\s>""'])";
public static Match GetMatchRegEx(string text)
{
return new Regex(UrlExtractor, RegexOptions.IgnoreCase).Match(text);
}
Here is how you can extract all Href Url. I'm using that regex in one of my projects, you can modify it to match your needs and rewrite it to match title as well. I guess it is more convenient to match them in bulk