Get all table tr data in single HtmlNodeCollection c# - c#

I need to retrieve all tr from all tables using HTML Agility Pack.
HTML:
<section class="content-section" id="more">
<div class="row">
<div class="col-xs-6"></div>
<div class="col-xs-6">
<h2>Specs</h2>
<div>
<div>
<table>
<thead>
<tr><th colspan="2"> test</th></tr>
</thead>
<tbody>
<tr><td>2</td><td>b</td></tr>
<tr><td>1</td><td>a</td></tr>
</tbody>
</table>
<table>
<tbody>
<tr><td>3</td><td>c</td></tr>
<tr><td>4</td><td>d</td></tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</section>
C#:
HtmlNodeCollection featuresNode = document.DocumentNode.SelectNodes("//*[#id='more']/div/div[2]/div/div[1]/table/tbody/tr");
I am only able to get first table tr but not getting all two table tr in HtmlNodeCollection.

To get all tr nodes including the one in thead, update your XPath to:
"//*[#id='more']/div/div[2]/div/div[1]/table//tr"
This simplified XPath should also work:
"//*[#id='more']//tr"
If you want only the tr from tbody, use:
"//*[#id='more']//tbody//tr"
Or excluding tr from thead, use:
"//*[#id='more']//tr[not(ancestor::thead)]"

Related

ASP.Net listview layout behaving oddly

I'm trying to use a ListView in an ASP.Net page and failing to get the results I was expecting. My page looks like this:
<table>
<tr>
<td><label class="subHeading">Contacts</label></td>
</tr>
<tr>
<asp:ListView runat="server" id="lvwContacts">
<LayoutTemplate>
<div class="tableWrapper">
<div class="tableScroll">
<table>
<tr>
<th><label>Full Name</label></th>
<th><label>Job Title</label></th>
<th><label>Direct Line</label></th>
<th><label>Mobile Phone</label></th>
<th><label>Email</label></th>
</tr>
<tr id="itemPlaceHolder" runat="server"></tr>
</table>
</div>
</div>
</LayoutTemplate>
<ItemTemplate>
<tr>
... etc
but when I look at the output the table is not appearing inside the divs:
<div class="tableWrapper">
<div class="tableScroll"></div>
</div>
<table>
<tbody>
<tr>
<td><label class="subHeading">Contacts</label></td>
</tr>
<tr></tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<th><label>Full Name</label></th>
<th><label>Job Title</label></th>
<th><label>Direct Line</label></th>
<th><label>Mobile Phone</label></th>
<th><label>Email</label></th>
</tr>
... etc
I've tried putting the divs around the whole listview with much the same result. What on earth is going on here? Have I done something stupid or do ListViews really behave like this?
Thanks
John
You must make sure you have valid HTML markup. Currently one of your <tr>'s has a <div> as a child, not a <td> or <th>.
See this demo:
/* style used to illustrate problem */
.tableWrapper {
padding: 10px;
background: red;
}
<label>Invalid markup</label>
<table>
<tr>
<td><label class="subHeading">Contacts</label></td>
</tr>
<tr> <!-- Invalid. child is a div not a td or th -->
<div class="tableWrapper">
<div class="tableScroll">
<table>
<tr>
<th><label>Full Name</label></th>
<th><label>Job Title</label></th>
<th><label>Direct Line</label></th>
<th><label>Mobile Phone</label></th>
<th><label>Email</label></th>
</tr>
</table>
</div>
</div>
</tr>
</table>
<hr>
<label>Valid markup</label>
<table>
<tr>
<td><label class="subHeading">Contacts</label></td>
</tr>
<tr>
<td> <!-- This is required! -->
<div class="tableWrapper">
<div class="tableScroll">
<table>
<tr>
<th><label>Full Name</label></th>
<th><label>Job Title</label></th>
<th><label>Direct Line</label></th>
<th><label>Mobile Phone</label></th>
<th><label>Email</label></th>
</tr>
</table>
</div>
</div>
</td>
</tr>
</table>
Inspect the rendered output of both tables... you will see what happens when the markup is not valid (what you are experiencing) the browser removes the <div> from the table. The second table has correct markup so it renders as-is

How can i add some pages to a table in razor

I created a view with two tabs.
One of the tabs has to be split in multiple pages.
Don't know how to do that with pagination.
Do i need a separate view for each tab or it can still be done in one view?
Can you please help me with an example for the same view?
<div class="w3-bar w3-dark-grey">
<button class="w3-bar-item w3-button tablink w3-red" onclick="openTab(event,'Statistics')">Statistics</button>
<button class="w3-bar-item w3-button tablink" onclick="openTab(event, 'History')">History</button>
</div>
<div id="History" class="w3-container w3-border city" style="display:none">
<h2>History</h2>
#helper ShowHistory(Site.classes.HistoryStruct[] aHistory)
{
<br>
<table class="table table-hover table-bordered">
<thead>
#if (aHistory == null)
{
<tr></tr>
}
else
{
<tr>
<th>Username</th>
<th>Info</th>
<th>Date</th>
</tr>
}
</thead>
<tbody id="tblStatistics">
#{string sClass = "class='divaproved'";
for (int i = 0; i < aHistory.Length; i++)
{
<tr #Html.Raw(sClass)>
<td>#aHistory[i].UserName</td>
<td>#aHistory[i].Info</td>
<td>#aHistory[i].Date</td>
</tr>
}
}
</tbody>
</table>
}
<div class="container">
#ShowHistory(Site.classes.UserAccessDB.aHistory)
</div>
</div>
If you just need to paginate your table you can try this js: DataTables
Give an ID to the table you need to paginate and add the following code at the end of your page
$(document).ready( function ()
{
$('#myTable').DataTable();
}
);

display anchor tag in angular expressions enclosed by html tag

I want to display an anchor tag inside angular expression enclosed by html tag. when I am using it inside html tag, it is displaying the raw path as it is which is:
<a href='../UserControls/DownloadRLCSFile.ashx?Path=\\\\dotnetdev\\csv\\RLCSDocuments\\Registrations\\ABACF\\E.S.I.C. Registration\\Sample.xlsx' target='_blank' download><i class='fa fa-download' style='font-size: 13pt;' ></i></a> Code :
<div id="Div2" ng-controller="BasicRegulatoryDetail">
<!--added by dilip -->
<h4 class="padder-sm b-b"><b>Regulatory Updates</b></h4>
<div>
<div class="table-responsive">
<table class="table table-striped bg-white ">
<%--<thead>
<tr>
<th>Subject</th>
<th>Download</th>
</tr>
</thead>--%>
<tbody>
<tr ng-repeat="bs in BasicInfo">
<td>
<asp:HyperLink ID="HyperLink1" NavigateUrl="~/RLCS_Connect/RegulatoryUpdateDetails.aspx?Subject={{bs.Subject}}" runat="server">{{bs.Subject}}</asp:HyperLink>
</td>
<td>{{bs.Document_Path}}</td>//here i am facing the problem </tr>
</tbody>
</table>
</div>
</div>
</div>
use ng-bind-html something like
<td><span ng-bind-html='bs.Document_Path'></span></td>

Iterate through html td's in Selenium Webdriver

I have 2 test cases in which i want to select the html and need to get the values of all td's
1. Need to select the 2nd html displayed in the webpage and iterate through the td's and get the value
2. Need to select the 3rd html displayed in the webpage and iterate through the td's and get the value.
Below is the html
<html> - 1st html in the page
<body>
<table>
<tbody>
<tr>
<td>..</td>
....
</tr>
.....
....
</tbody>
</table>
</body>
</html>
<iframe> - Parent
<iframe tabindex="-1" frameborder="no" width="100%" src="about:blank" class="active">
<html> - 2nd html in the page
<body>
<table>
<tbody>
<tr>
<td>..</td>
<td>..</td>
<td>..</td>
</tr>
<tr>
<td>..</td>
<td>..</td>
<td>..</td>
</tr>
<tr>
<td>..</td>
<td>..</td>
<td>..</td>
</tr>
....
....
.....
<tbody>
</table>
</body>
</html>
</iframe>
<iframe tabindex="-1" frameborder="no" width="100%" src="about:blank" class="active">
<html> - 3rd html in the page
<body>
<table>
<tbody>
<tr>
<td>..</td>
<td>..</td>
<td>..</td>
</tr>
<tr>
<td>..</td>
<td>..</td>
<td>..</td>
</tr>
<tbody>
</table>
</body>
</html>
</iframe>
</iframe>
FYI, I'm switching to the IFrame before finding the element
driver.SwitchTo().Frame(); - outerframe
driver.SwitchTo().Frame(); - InnerFrame
I tried the below one to find the element, but it is selecting the first html element on the webpage.
List<IWebElement> elements = driver.FindElement(By.XPath("/html/body/table/tbody")).FindElements(By.TagName("tr")).ToList();
Could anyone help me out on this?
Thanks
Try this:
var frames = driver.FindElements(By.TagName("iframe")).ToList()
driver.switchTo().frames[1];
tds = WebDriver.FindElements.(By.Tagname("td");;
var td = tds.Where(ele=>ele.Text=="Something").ToList();
You should use code like below:
List<WebElement> elements = driver.findElements(By.xpath(""));
for(WebElement el: elements){
String value = el.findElement(By.tagName(td)).getText();
System.out.println(value);
}
While iterating frame td's you should select frame first then apply same as above code

Automatic Web content downloading using C#

I want to develop a program to automatically lookup words in Longman online dictionary and copy its definition and meanings. I am using visual studio and C# language and I have developed the part which browse to the website and search for a word. However, the problem is in navigating through Longman online website when there are some word forms. for example for this link the html code of the suggested words is as following:
<div class="content1">
<style>
.dictionary-results-title .topic_bullet {
margin: 0px;
}
</style>
<div class="border-search">
<div class="dictionary-results-title">
Results from the Longman Dictionary of Contemporary English:
</div>
<div class="dictionary-results-title">
<span class="dictionary-results-title-topic-new">
Click on topic labels to navigate through our Topic Dictionary
</span>
</div>
<!-- google_ad_section_start -->
<div id="42385" class="folded">
<table id="hwdfolded" class="hwdfolded" cellspacing="0" cellpadding="0">
<tr>
<td class="hwdunSelHG"></td>
<td class="hwdunSelHM"></td>
<td class="hwdunSelHD"></td>
</tr>
<tr>
<td class="hwdunSelMG"></td>
<td class="hwdunSelMM">
<a href="/dictionary/superman">
<span class="headword">superman</span></a>
<span class="homographs"></span>
<span class="wordclass">noun</span>
<span class="topiclinks"></span>
</td>
<td class="hwdunSelMD"></td>
</tr>
<tr>
<td class="hwdunSelBG"></td>
<td class="hwdunSelBM"></td>
<td class="hwdunSelBD"></td>
</tr>
</table>
</div>
<div id="42386" class="folded">
<table id="hwdfolded" class="hwdfolded" cellspacing="0" cellpadding="0">
<tr>
<td class="hwdunSelHG"></td>
<td class="hwdunSelHM"></td>
<td class="hwdunSelHD"></td>
</tr>
<tr>
<td class="hwdunSelMG"></td>
<td class="hwdunSelMM">
<a href="/dictionary/Superman">
<span class="headword">Superman</span></a>
<span class="homographs"></span>
<span class="wordclass"></span>
<span class="topiclinks"></span>
</td>
<td class="hwdunSelMD"></td>
</tr>
<tr>
<td class="hwdunSelBG"></td>
<td class="hwdunSelBM"></td>
<td class="hwdunSelBD"></td>
</tr>
</table>
</div>
<script language="JavaScript" type="text/javascript">
parent.curEntryId=42385; parent.prevEntryId=42385; parent.nextEntryId=42385;
parent.gsSenseId=null; parent.giPhrId=null;
</script>
</div>
</div>
I have found the way to find the ID of the words like id="42385" and id="42386" but I cannot navigate through them. There is a table inside each element with these ids. As you can see in the html code the second data of the second row of the table contains the links for each word.
the code I have written to click on them is like this:
HtmlElement Word = webBrowser1.Document.GetElementById("hwdfolded");
foreach (HtmlElement ele in Word.Parent.Parent.Children)
{
if (ele.Id != null && ele.InnerText.ToLower().Contains(Stword))
{
HtmlElement clickon = webBrowser1.Document.GetElementById(ele.Id);
clickon.InvokeMember("click");
//ele.InvokeMember("click");
while (webBrowser1.ReadyState != WebBrowserReadyState.Interactive)
Application.DoEvents();
do
{
Application.DoEvents();
} while (webBrowser1.ReadyState != WebBrowserReadyState.Complete);
break;
}
}
Note that Stword contains the string of the word I am searching for in this example it contains "superman" and also the ele.Id contains one the specified Ids and I checked it in debug mode. But the click command not works. I will appreciate it if you can tell me the solution or give me another solution which is better.
I suggest that you use a scraping tool to perform the navigation through the page. With Selenium it is really easy to obtain elements by XPATH and navigate through them and also obtain the text inside them. Hope it helps.

Categories

Resources