I have ASP.NET MVC4 project where try to parse html document with HtmlAgilityPack. I have the following HTML:
<td class="pl22">
<p class='pb10 pt10 t_grey'>Experience:</p>
<p class='bold'>any</p>
</td>
<td class='pb10 pl20'>
<p class='t_grey pb10 pt10'>Education:</p>
<p class='bold'>any</p>
</td>
<td class='pb10 pl20'>
<p class='pb10 pt10 t_grey'>Schedule:</p>
<p class='bold'>part-time</p>
<p class='text_12'>2/2 (day/night)</p>
</td>
I need to get values:
"any" after "Experience:"
"any" after "Education:"
"part-time", "2/2 (day/night)" after "Schedule:"
All what I imagine is that
HtmlNode experience = hd.DocumentNode.SelectSingleNode("//td[#class='pl22']//p[#class='bold']");
But it get me different element, which place in the top of the page. My Experience, Education and Schedule is static values. In additional my any, any part-time day/night is the dynamic values. Can anybody help me?
Below is an alternative which is more focused on the table headers (Experience, Education and Schedule), instead of the node classes:
private static List<string> GetValues(HtmlDocument doc, string header) {
return doc.DocumentNode.SelectNodes(string.Format("//p[contains(text(), '{0}')]/following-sibling::p", header)).Select(x => x.InnerText).ToList();
}
You can call that method like this:
var experiences = GetValues(doc, "Experience");
var educations = GetValues(doc, "Education");
var schedules = GetValues(doc, "Schedule");
experiences.ForEach(Console.WriteLine);
educations.ForEach(Console.WriteLine);
schedules.ForEach(Console.WriteLine);
You could do it something like this if you want to keep the XPath
var html = "<td class='pl22'><p class='pb10 pt10 t_grey'>Experience:</p><p class='bold'>any</p></td><td class='pb10 pl20'><p class='t_grey pb10 pt10'>Education:</p><p class='bold'>any</p></td><td class='pb10 pl20'><p class='pb10 pt10 t_grey'>Schedule:</p><p class='bold'>part-time</p><p class='text_12'>2/2 (day/night)</p></td> ";
var doc = new HtmlDocument
{
OptionDefaultStreamEncoding = Encoding.UTF8
};
doc.LoadHtml(html);
var part1 = doc.DocumentNode.SelectSingleNode("//td[#class='pl22']/p[#class='bold']");
var part2 = doc.DocumentNode.SelectNodes("//td[#class='pb10 pl20']/p[#class='bold']");
foreach (var item in part2)
{
Console.WriteLine(item.InnerText);
}
var part3 = doc.DocumentNode.SelectSingleNode("//td[#class='pb10 pl20']/p[#class='text_12']");
Console.WriteLine(part1.InnerText);
Console.WriteLine(part3.InnerText);
Output :
any
part-time
any
2/2 (day/night)
Related
Hello guys specially VueJS devs theres something weird happened. Ill explain it one by one
Full video:
https://drive.google.com/file/d/1G2ksQsMQ1LB868dg29f8mm4NR_x5GycF/view?fbclid=IwAR1YmYbo3J6jHrY6PHd8E_lxA47VJSXV6G3132_uF6Or3bXv7MbnQbRvKaU
I use datatable and then i use this getDefaultPrice() to manipulate the price because the format of my price is like this ("65;75") to return the first value to PHP 65.00
then once i click the add to cart button please see image for codes the getDefaultPrice() also executed.
and I received an error "price.split is not a function" I tried to console.log the function and it really runs it without calling it in my add_to_cart();
<td>
<p>{{getDefaultPrice(product.price)}}</p>
</td>
<td>
<button
class="btn main_bg_color add_to_cart_btn" data-toggle="modal" data-target="#productModal"
#click="add_to_cart(product)"
>
<i class="fa fa-shopping-cart"></i> Add to cart
</button>
</td>
add_to_cart(product) {
this.modal_data = [];
this.modal_data.push(product)
this.modal_data[0].variation = this.modal_data[0].variation.split(';');
this.modal_data[0].price = this.modal_data[0].price.split(';');
this.modal_data[0].drinks_price = this.modal_data[0].drinks_price.split(';');
this.modal_data[0].drinks = this.modal_data[0].drinks.split(';');
},
getDefaultPrice(price) {
console.log("test")
var price_arr = price.split(";");
var default_price = parseFloat(price_arr[0]);
return "PHP " + default_price.toFixed(2);
},
How do i call a controller from anchor tag when Controller is on the:
Area->Ticket->TicketController
Here is the code:
<a href="#Url.Action("TicketTemplate", "MyTickets", new {area = string.Empty,controller = "TicketTemplate", page = Model.PageNumber, sort = "DateCreated ", isAsc = isAsc })">
Date Created
<span class="#clsDateCreated" style="text-align: right;"></span>
</a>
The above code is not working..
How do i call the controller??
Here is the path:
~/Areas/Ticket/Controllers/TicketTemplateController.cs
You can do that and it will work, but i don't know if there is a better solution or not.
<a href="#Url.Action("MyTickets", "Ticket/TicketTemplate", , new {area = string.Empty,controller = "TicketTemplate", page = Model.PageNumber, sort = "DateCreated ", isAsc = isAsc })">
Date Created
<span class="#clsDateCreated" style="text-align: right;"></span>
</a>
I'm obviously missing something obvious here but I cant for the life of me work out what, I've setup a view to display a custom SQL query, but the screen is showing nothing, here's what I've got
Controller
def queueBreakdown(){
String SQLQuery = "select state, count(test_exec_queue_id) as 'myCount' from dbo.test_exec_queue group by state"
def dataSource
def list = {
def db = new Sql(dataSource)
def results = db.rows(SQLQuery)
[results:results]
}
}
If I run this manually I get a set of results back like so
state myCount
1 1
test 2
test2 1
The queueBreakdown.gsp has the following...
<body>
<g:message code="default.link.skip.label" default="Skip to content…"/>
<div class="nav" role="navigation">
<ul>
<li><a class="home" href="${createLink(uri: '/')}"><g:message code="default.home.label"/></a></li>
</ul>
</div>
<div id="queueBreakdown-testExecQueue" class="content scaffold-list" role="main">
<h1><g:message code="Execution Queue Breakdown" /></h1>
<table>
<thead>
<tr>
<g:sortableColumn property="Run State" title="Run State"/>
<g:sortableColumn property="Count" title="Count" />
</tr>
</thead>
<tbody>
<g:each in="${results}" status="i" var="it">
<tr class="${(i % 2) == 0 ? 'even' : 'odd'}">
<td>${it.state}</td>
<td>${it.myCount}</td>
</tr>
</g:each>
</tbody>
</table>
</div>
</body>
But when I view the page I get nothing... The table has been built but there are no lines in it, what am I being thick about here?
Cheers
your controller code is really confusing, what is the action here ? queueBreakdown() or list() ? It seems like you have mixed up 2 actions together, and queueBreakdown() is not returning any model...
class SomeController {
def dataSource
def queueBreakdown() {
String SQLQuery = "select state, count(test_exec_queue_id) as 'myCount' from dbo.test_exec_queue group by state"
def db = new Sql(dataSource)
def results = db.rows(SQLQuery)
[results:results]
}
}
Below is my code:
#{
Layout = "/_SiteLayout.cshtml";
var db = Database.Open("MyDatabase");
var query = "SELECT * FROM Team";
var Teams = db.Query(query);
}
<form>
<table>
<tr>
<td>Team Name</td>
<td>Played</td>
<td>Points</td>
</tr>
#{ foreach(var Team in Teams){
<tr>
<td>#Team.TeamName</td>
<td><input type="text" value="#Team.Played" name="Played"/></td>
<td><input type="text" value="#Team.Points" name="Points"/></td>
</tr>
}
}
</table>
</form>
This is the result:
So what I want to do is update my whole table.
What is the SQL query to do this? I want to update Points and Games Played in my database for all teams once the form is posted.
I don't actually understand what exactly you are trying to achieve (update your whole table with what?), but here is some information you might find useful:
SQL Update Tutorial, SQL Update, Update from Select
Following is My Solution. Anyone have an efficient Solution?
#{
var db = Database.Open("MYDATABSE");
var query = "SELECT * FROM Team";
var Teams = db.Query(query);
var InsertQuery = "";
if(IsPost){
foreach(var Team in Teams){
var Points = Request[Team.TeamName];
var TeamId = Team.TeamId.ToString();
var Played = Request[TeamId];
var executeQueryString="UPDATE Team Set Points=#0, Played=#1 WHERE TeamId=#2";
db.Execute(executeQueryString, Points, Played, Team.TeamId);
}
Response.Redirect("~/UpdateTable.cshtml");
}
}
<br /><br />
<form action="" method="post">
<table>
<tr>
<td><h5>Team Name</h5></td>
<td><h5>Played</h5></td>
<td><h5>Points</h5></td>
</tr>
#{ foreach(var Team in Teams){
<tr>
<td>#Team.TeamName</td>
<td><input type="text" value="#Team.Played" name="#Team.TeamId"/></td>
<td><input type="text" value="#Team.Points" name="#Team.TeamName"/></td>
</tr>
}
}
<table >
<tr class="odd First"><td>1one Cell</td><td>2one Cell</td><td>3one Cell</td><td>4one Cell</td> </tr>
<tr class="even Second"><td>Two Cell</td><td>2Two Cell</td><td>3Two Cell</td><td>4Two Cell</td></tr>
<tr class="odd Thrid"><td>1Three Cell</td><td>2Three Cell</td><td>3Three Cell</td><td>4Three Cell</td></tr>
<tr class="even Fourth"><td>1Five Cell</td><td>2Five Cell</td><td>3Five Cell</td><td>4Five Cell</td></tr>
</table>
How can i get the class names of the tr. Please suggest me.
To get the class names of all the tags using java.
List<WebElement> list = driver.findElements(By.tagName("tr"));
for(WebElement ele:list){
String className = ele.getAttribute("class");
System.out.println("Class name = "+className);
}
This will print all the class names to the console for all the tags on the web page.
String className = selenium.getAttribute("//html/body/table/tbody/tr[1]/#class");
May be this code might get you the value of the first tag's class name. Let me know if this works.
List0 = []
List1 = driver.find_elements(By.XPATH, '/table/tr')
for element in List1:
name = element.get_attribute('class')
List0.append(name)
print(List0)