Here is the problem
<input type='text'name='TextBox0001'/>
For example to insert a value for the input of above is just by using this code :
foreach (HtmlElement he in webBrowser1.Document.All.GetElementsByName("TextBox0001"))
{
he.SetAttribute("value", "HI");
}
That's okay but how do I insert a value for the counter if the html code written like below?
<table>
<tr id='set1_row1'>
<td> <input type='text'name='counter'></td>
</tr>
<tr id='set1_row2'>
<td> <input type='text'name='counter'></td>
</tr>
</table>
</table>
I am using c# webBrowser.
For "set1_row1" would be:
foreach (HtmlElement he in webBrowser1.Document.All.GetElementsByName("counter"))
{
if(he.Parent.Parent.getAttribute("id") == "set1_row1")
{
he.SetAttribute("value", "HI");
}
}
You get the idea, so you can figure out your exact logic based on this example.
Related
I'm working on a Blazor component with a table where it makes sense to factor out a couple pieces of the template. However it's not rendering correctly and the td elements I'm producing are not ending up inside the tr element, but instead are at the same level.
Below is a simplified version of the code. The body has the problem while the footer renders correctly. What is the correct way to accomplish what I'm trying to here? I know I could avoid all of the Razor syntax and just create a function that returns a raw MarkupString, but that doesn't seem like it should be necessary for a case like this.
<table>
<tbody>
#foreach (var row in data)
{
#:<tr>
RenderRow(row);
#:</tr>
}
</tbody>
<tfoot>
<tr>
#if (footerRow != null)
{
RenderRow(footerRow);
}
</tr>
</tfoot>
</table>
#{
void RenderRow(Row row)
{
<td>#row.RowNum</td>
RenderRowHalf(row.Left);
RenderRowHalf(row.Right);
}
void RenderRowHalf(RowHalf half)
{
<td>#half.Foo</td>
<td>#(Util.ColorNumber(half.Bar))</td>
}
}
A lot to unpick here - using #: before the <tr>, then calling a C# method is switching context and Blazor will auto-close the tag - get rid of the #: - not needed.
Change your methods to return RenderFragment<T> - the Blazor way of creating a fragment of Razor markup. Call them with # prefix to switch back to C#.
The <text> tag helper just provides a way to group markup in the C# code sectiion.
Use #code for your C# code, otherwise it is scoped to each render cycle.
<table>
<tbody>
#foreach (var row in data)
{
<tr>
#RenderRow(row)
</tr>
}
</tbody>
<tfoot>
<tr>
#if (footerRow != null)
{
#RenderRow(footerRow)
}
</tr>
</tfoot>
</table>
#code
{
RenderFragment<Row> RenderRow => row =>
#<text>
<td>#row.RowNum</td>
#RenderRowHalf(row.Left)
#RenderRowHalf(row.Right)
</text>
;
RenderFragment<RowHalf> RenderRowHalf => half =>
#<text>
<td>#half.Foo</td>
<td>#(Util.ColorNumber(half.Bar))</td>
</text>
;
}
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 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));
});
});
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