I have exhausted my mental resources and can't solve this puzzle. I am attempting to extract the text from the span with id = "lookupCount". I want the "9" from there, but no matter how hard I try, it doesn't work. Please help, below is the html.
Just to be clear, i want the value of this text - "9"
<div class="addressSelectionDiv" style="width:330px; margin-left:0px; margin-top:40px; ">
<table id="addressSelectionTable" align="center" width="100%" cellspacing="2" cellpadding="0">
<tbody>
<tr style="height:15px;">
<td>
<div id="App.ctl00_leftContent_addressSelection_validationLabel_Container" style="display:inline;">
<label id="ctl00_leftContent_addressSelection_validationLabel" class="x-label x-label-default x-border-box" for="" style="color:#981e32;font-size:1.0em;">
<img id="ext-gen1029" class="x-label-icon" src="data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" style="display: none;"/>
<span id="ext-gen1030" class="x-label-value"/>
</label>
</div>
<span id="lookups" style="visibility: hidden; float: right;">
<span id="lookupCount">9</span>
/
<span id="lookupLimit">100</span>
</span>
</td>
</tr>
<tr valign="top">
<tr>
</tbody>
</table>
</div>
Here is what I tried
var x = Driver.FindElement(By.Id("lookupCount")).Text returns ""
var x = Driver.FindElement(By.Id("lookups")).Text returns ""
Neither of the objects above contain any information that leads me to the answer, even if I remove the .Text property.
The 2 lines below returns "" in the [0]th element.
ICollection<IWebElement> table = Driver.FindElements(By.Id("lookups"));
List<IWebElement> elements = table.ToList();
The one below returns this string:
Search for Household Decisions by entering an address or ZIP code:\r\n\r\n AL\r\n AK\r\n AZ\r\n AR\r\n CA\r\n CO\r\n CT\r\n DC\r\n DE\r\n FL\r\n GA\r\n HI\r\n ID\r\n IL\r\n IN\r\n IA\r\n KS\r\n KY\r\n LA\r\n ME\r\n MD\r\n MA\r\n MI\r\n MN\r\n MS\r\n MO\r\n MT\r\n NE\r\n NV\r\n NH\r\n NJ\r\n NM\r\n NY\r\n NC\r\n ND\r\n OH\r\n OK\r\n OR\r\n PA\r\n RI\r\n SC\r\n SD\r\n TN\r\n TX\r\n UT\r\n VT\r\n VA\r\n WA\r\n WV\r\n WI\r\n WY
ICollection<IWebElement> table = Driver.FindElements(By.Id("addressSelectionTable"));
List<IWebElement> elements = table.ToList();
Returns text located between open/close tag of the element with Id "lookupCount":
driver.FindElement(By.Id("lookupCount")).Text;
Returns html code between open/close tag with id "lookupCount":
driver.FindElement(By.Id("lookupCount")).HtmlInner;
Related
I want to fetch data from SQL and display in HTML table using ng-repeat option then I need to edit some values in the table cell. My problem is that I only get initial values in the controller and the changes are not reflected in the controller. Here is my code:
app.controller('CRUD_EntryController', function ($scope, CRUD_InternalEntryService) {
GetStudentMarkDetails();
function GetStudentMarkDetails() {
var PromiseGetMarks = CRUD_InternalEntryService.GetMarkDetails();
PromiseGetMarks.then(function (res) {
$scope.MarkList = res.data;
})
}
$scope.mark = {};
$scope.save = function (MarkList) {
var index = 0;
$scope.MarkList.forEach(function (mark) {
console.log('rows #' + (index++) + ': ' + JSON.stringify(mark));
alert(mark.M1);
}
}
View:
<table class=" table table-condensed" id="myresul">
<tr>
<th>Slno</th>
<th>Name</th>
<th>RegNo</th>
<th>ClassNo</th>
<th>M1</th>
<th>M2</th>
<th>M3</th>
</tr>
<tbody data-ng-repeat="mark in MarkList" >
<tr>
<td class="col-md-1" >#{{$index+1}}</td>
<td class="col-md-2" ng-model="mark.Fname">{{mark.Fname}}</td>
<td class="col-md-2">{{mark.RegNo}}</td>
<td class="col-md-1">{{mark.ClassNo}}</td>
<td class="col-md-1"><input type="number" value="{{mark.M1}}" ng-model="M1" class="form-control" /></td>
<td class="col-md-1"><input type="number" value="{{mark.M2}}" ng-model="M2" class="form-control" /></td>
<td class="col-md-1"><input type="number" value="{{mark.M3}}" ng-model="M3" class="form-control" /></td>
</tr>
<button data-ng-click="save(MarkList)" class="btn btn-success">Save</button>
</tbody>
</table>
Don't think you need to define this: $scope.mark = {}; since mark is set in the scope of your ng-repeat. Remove it because this is somewhat confusing and might cause errors in the future.
Remove the value="{{mark.M1}}" and bind your model to ng-model="{{mark.M1}}". Asuming that you wand to bind to M1, M2 and M3 in your inputs.
Also see the angular docs for ngModel for more details and update your code accordingly.
By the way you don't have to pass MarkList as an argument for Save(..), you can do this:
<button data-ng-click="save()" class="btn btn-success">Save</button>, change the Save method signature to Save() and use $scope.MarkList instead of the argument MarkList.
Or change your method to only save the specific mark instead of the entire list every time.
I have the following code in which I am showing and hiding html controls based on Dropdown list selected value. Show and Hide is working fine but I want to Check in backend i.e C# that the which <tr> is visible and which one is hidden.
Here is my aspx page code
<script type="text/javascript">
$(document).ready(function () {
$("#AttachemntType").change(function () {
if ($(this).val() == "F") {
$("#tr_CompileFile").show();
$("#tr_SourceFile").show();
}
else if ($(this).val() == "R") {
$("#tr_CompileFile").hide();
$("#tr_SourceFile").show();
}
else {
$("#tr_SourceFile").hide();
$("#tr_CompileFile").hide();
}
});
});
</script>
<tr bgcolor="white">
<td style="height: 20px">
Attachment Type
</td>
<td>
<select id="AttachemntType" name="AttachemntType" style="width: 344px">
<option value="0">Select</option>
<option value="F">Form</option>
<option value="R">Report</option>
</select>
</td>
</tr>
<tr bgcolor="white" id="tr_SourceFile" style="display:none;" runat="server">
<td style="height: 20px">
Source File
</td>
<td>
<input class="body_text" type="file" id="src_File" name="src_File" runat="server"
style="width: 420px" />
</td>
</tr>
<tr bgcolor="white" id="tr_CompileFile" style="display:none;" runat="server">
<td style="height: 20px">
Compiled File
</td>
<td style="height: 16px; width: 625px;">
<input class="body_text" type="file" id="comp_File" runat="server" style="width: 420px" />
</td>
</tr>
This is the code which I am trying in Backend but its returning always true for all fields
if (tr_CompileFile.Visible == true && tr_SourceFile.Visible == true)
{
//This Condition is always true
}
else if (tr_SourceFile.Visible == true && tr_CompileFile.Visible == false)
{
//something
}
else
{
//something else
}
You cannot actually check this in backend. .show() and .hide() are jQuery methods which only operates on client side.
One workaround could be to use a MVVM pattern with knockout.js (Don’t try angular for that, you’ll be lost in docs)
Another option is to actually put your select box and the hidden/visible parts into UpdatePanel. So when you change the selector, the server side is called and you can assign / remove “visible” field.
More : https://msdn.microsoft.com/en-us/library/bb399001.aspx
In last resort, you can put a hidden field, which will be populated on submit with “hidden,shown,etc” values for you inputs.
Personally, I’ll vote for the first, but second is the easiest one to implement
Yes, Jurion was right. just adding more explanation: you can try
tr_CompileFile.Style["HTML Style key here"]
for example you can try
tr_CompileFile.Style["display"]
but it will return to you the value of the particular style defined in your aspx files, not the actual style displayed and changed in client side.
If you defined
<asp:Button ID="btnTest" runat="server" style="display:none" />
when you check it,
btnTest.Style["display"]
will return "none"
This is a a page from an open databse about food:
http://www.dabas.com/ProductSheet/Details.ashx/121308
Im trying to get some info from this page using XPath.
The table I'm interested in is the one called: Näringsvärde.
I want to get all the textnodes inside "Näringsvärde" saved into a string.
This is the relevant portion of the code linked above:
<!DOCTYPE html>
<html>
...
<body>
...
<table class="width100" style="page-break-inside: avoid">
<caption>
Produktinformation
<img src="../../images/ProductSheet/draw-triangle3.png" id="toggleProduktinformation"
class="imgCaptionOn" />
</caption>
<tbody id="tbodyProduktinformation">
<tr>
<td class="col1">
Ursprungsland:
</td>
<td>
Sverige </td>
</tr>
...
</tbody>
</table>
<table id="tableHover" class="width100 marginTop30 bgTable">
<tr class="nohover">
<td class="tdLeft48 padding0">
<table id="nutritiveTabel" class="leftTable" style="page-break-inside: avoid">
<caption>
Näringsvärde
<img src="../../images/ProductSheet/draw-triangle3.png" id="toggleNutritiveValues"
class="imgCaptionOn" />
</caption>
<tbody id="tbodyNutritiveValues">
<tr id="divNutritiveValues">
<td class="padding">
<table class="noBorder width100">
<tr>
<td class="col1">
Tillagningsstatus:
</td>
<td>Tillagad</td>
<td colspan="2">
&nbsp;
</td>
</tr>
...
</table>
</td>
</tr>
</tbody>
</table>
</td>
...
</html>
I tried using something like this so far, but it didn't work:
public List<string> GetNaring(string xid) {
HtmlWeb web = new HtmlWeb();
HtmlDocument doc = web.Load(xid);
var xpath = "/html/body/div/div[2]/div[2]/table[2]/tbody/tr/td/table/tbody";
var links = doc.DocumentNode.SelectNodes(xpath);
return links.Select(n => n.InnerText).ToList();
}
But this only gives back null, what am I missing?
The XPath expression:
/html/body/div/div[2]/div[2]/table[2]/tbody/tr/td/table/tbody
does not match any nodes.
Since you have an unique string you can match, you should use it. Searching for that string in the source code, you will find:
...
<td class="tdLeft48 padding0">
<table id="nutritiveTabel" class="leftTable" style="page-break-inside: avoid">
<caption>
Näringsvärde
<img src="../../images/ProductSheet/draw-triangle3.png" id="toggleNutritiveValues"
class="imgCaptionOn" />
</caption>
<tbody id="tbodyNutritiveValues">
<tr id="divNutritiveValues">
...
The string is a child of the caption element inside the table you want. You have to get the string value of that element, trim the extra spaces and use the result to compare to "Näringsvärde". You can select the correct table using this expression:
//table[normalize-space(caption/text())='Näringsvärde']
Once you have the correct table, you can navigate inside it and select the nodes you want, or you can get the string-value which is a concatenation of all the descendant text nodes:
//table[normalize-space(caption/text())='Näringsvärde']//td
This will return all td nodes, which is where the text is.
Hello i making HttpWebResponse and getting the HtmlPage with all data that i need for example table with date info that i need to save them to array list and save it to xml file
Example of html Page
<tbody>
<tr class="odd">
<tr class="even">
<td class="padding5 sorting_1">
<span class="DateHover" sort="14/03/18/22/56" title="18.03.14" ref="18.03.14">18.03.14</span>
</td>
<td class="CellStyleDefaultText">
<span class="transSpan">Info</span>
</td>
<td class="CellStyleDefaultText" title="UserNumber123">UserNumber123</td>
<td class="CellStyleSignedNumber floatopHomePage">
<span title="701,554.23 ">701,554.23 </span>
</td>
<td class="CellStyleAmount CellStyleAmountNew">
<div title="-3354999.71">-3354999.71</div>
</td>
<td class="CellStyleDetails CCMoreDetailsTd">
<span> 17.03.14 Info</span>
</td>
</tr>
</tbody>
Ok the first span with dateTime i got
foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//span[#class='DateHover']"))
span with info
foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//td[#class='transSpan']"))
and then i stuck to get UserNumber123 i did this
foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//td[#class='CellStyleDefaultText']"))
but it returns me span transSpan as well because it in td
and all others td CellStyleSignedNumber,CellStyleAmount,CellStyleDetails i can't get.
Any ideas?
You can simply mention the attribute name to select element that has particular attribute set. So you can try to get UserNumber123 this way :
doc.DocumentNode.SelectNodes("//td[#class='CellStyleDefaultText' and #title]")
Above XPath means, select <td> element that has title attribute and hass class attribute value equals 'CellStyleDefaultText'.
For the rest <td>, try to use XPath contains() function, for example :
doc.DocumentNode.SelectNodes("//td[contains(#class,'CellStyleSignedNumber')]")
UPDATE :
Responding the latter part of your comment, if you intend to get <td> that has child <span>element, you can add the criteria as simple as following :
doc.DocumentNode.SelectNodes("//td[span and contains(#class,'CellStyleSignedNumber')]")
I have a table like that. And I wanna get the just text FOO COMPANY from between td tags. How can I get it?
<table class="left_company">
<tr>
<td style="BORDER-RIGHT: medium none; bordercolor="#FF0000" align="left" width="291" bgcolor="#FF0000">
<table cellspacing="0" cellpadding="0" width="103%" border="0">
<tr style="CURSOR: hand" onclick="window.open('http://www.foo.com')">
<td class="title_post" title="FOO" valign="center" align="left" colspan="2">
<font style="font-weight: 700" face="Tahoma" color="#FFFFFF" size="2">***FOO COMPANY***</font>
</td>
</tr>
</table>
</td>
</tr>
<table>
I'm using following code but nS is null.
doc = hw.Load("http://www.foo.aspx?page=" + j);
foreach (HtmlNode link in doc.DocumentNode.SelectNodes("//table[#class='left_company']"))
{
nS = doc.DocumentNode.SelectNodes("//td[#class='title_post']");
}
var text = doc.DocumentNode.Descendants()
.FirstOrDefault(n => n.Attributes["class"] != null &&
n.Attributes["class"].Value == "title_post")
.Element("font").InnerText;
or
var text2 = doc.DocumentNode.SelectNodes("//td[#class='title_post']/font")
.First().InnerText;
Likely the page you are calling generate the content of interest using JavaScript. HtmlAgilityPack does not execute JavaScript, so the content cannot be extracted. One way to confirm this is to try to visit the page with scripting turned off, and try to see if the element you are interested in still exists.
insert some attribute to font element like company="FOO"
then use jquery to get that element like
alert($('font[company="FOO"]').html())
like this
cheers
Close: nS = doc.DocumentNode.SelectNodes("//td[#class='title_post']//text()");
You can then open the nS node to retrieve the text. If there's more than one text node, you'll need to iterate over them.