Ruby - extracting table values - ruby

I'm trying to parse a value from an HTML table (below) using ruby, watir and regular expressions. I want to parse the id info from the anchor tag if the table rows have specified values. For example, if Event1, Action2 are my target row selections, then my goal is to get the "edit_#" for the table row.
Table:
Event1 | Action2
Event2 | Action3
Event3 | Action4
Example of HTML (I've cut some info out since this is work code, hopefully you get the idea):
<div id="table1">
<table class="table1" cellspacing="0">
<tbody>
<tr>
<tr class="normal">
<td>Event1</td>
<td>Action2</td>
<td>
<a id="edit_3162" blah blah blah… >
</a>
</td>
</tr>
<tr class="alt">
<td> Event2</td>
<td>Action3 </td>
<td>
<a id="edit_3163" " blah blah blah…>
</a>
</td>
</tr>
</tbody>
</table>
</div>
I have tried the following that doesn't really work:
wb=Watir::Browser.new
wb.goto "myURLtoSomepage"
event = "Event1"
action = "Action2"
table = browser.div(:id, "table1")
policy_row = table.trs(:text, /#{event}#{action/)
puts policy_row
policy_id = policy_row.html.match(/edit_(\d*)/)[1]
puts policy_id
This results in this error which is pointing to the policy_id = ...
line : undefined method 'html' for #<Watir::TableRowCollection:0x000000029478f0> (NoMethodError)
Any help is appreciated as I am fairly new to ruby and watir.

Something like this should work:
browser.table.trs.each do |tr|
p tr.a.id if tr.td(:index => 0) == "Event1" and tr.td(:index => 1) == "Action2"
end

This is an alternative to Željko answer. Assuming there is only one row that matches, you can use find instead of each to only iterate through the rows until the first match is found (rather than always going through every row).
#The table you want to work with
table = wb.div(:id => 'table1').table
#Find the row with the link based on its tds
matching_row = table.rows.find{ |tr| tr.td(:index => 0).text == "Event1" and tr.td(:index => 1).text == "Action2" }
#Get the id of the link in the row
matching_row.a.id

Related

Loop inside loop with record count for each row of the last loop

I have 3 tables: dbo.Category, dbo.SubCategory and dbo.Product with the following structure:
dbo.Category: (Category_ID, Category_name)
dbo.SubCategory: (SubCategory_ID, Category_ID, SubCategory_name)
dbo.Product: (Product_ID, Category_ID, SubCategory_ID, Product_name)
I need a loop to display all my categories (from the Category table)
I need a second loop (inside the first one) to display all the subcategories belonging to the parent category.
I need to display (with record count) how many products have each one of my subcategories.
For example, I need something like this:
Category 1
--- Subcategory1 (7)
--- Subcategory 2 (11)
Category 2
--- Subcategory 5 (88)
--- Subcategory 9 (36)
Category 3
--- Subcategory 8 (0)
--- Subcategory 22 (122)
I am not familiar with classic asp and vbscript and the only thing I have managed to do until now, is only the first loop with my main Categories as following:
<%
dim Connect,RS_test,sql
Set Connect = Server.Createobject("ADODB.Connection")
Connect.Open = MM_sindesi_STRING
sql = "SELECT * FROM dbo.Category"
set RS_test = Connect.Execute(sql)
%>
<%
Do Until RS_test.Eof
%>
<table width="100%" border="1" cellspacing="1" cellpadding="1">
<tr>
<td><%=RS_test("Category_name")%></td>
</tr>
</table>
<%
RS_test.MoveNext
Loop
%>
<%
Connect.Close()
Set RS_test = Nothing
Set Connect = Nothing
%>
The above code works ok but the only thing I am getting are the names of my categories…
I have tried so hard to find some similar questions in stackoverflow but unfortunately I didn’t managed to find anything…
You use nested Do Loop
<%
set category = server.createobject("adodb.recordset")
SQL="SELECT * FROM dbo.Category"
category.open SQL,Connect,1,3
%>
<%i=0%>
<% Do while not category.eof %>
<%i=i+1%>
<%=i> Category Record
<table width="100%" border="1" cellspacing="1" cellpadding="1">
<tr>
<td><%=category("Category_name")%></td>
</tr>
<%
cat_id=category(Category_ID)
set sub_category = server.createobject("adodb.recordset")
SQL="SELECT * FROM dbo.SubCategory where Category_Id="&cat_id&""
sub_category.open SQL,Connect,1,3%>
<%j=0%>
<% Do while not sub_category.eof %>
<%j=j+1%>
<%=j%> Record Sub Category
<tr>
<td><%=category("SubCategory_name")%></td>
</tr>
<%
sub_category.MoveNext
Loop
%>
</table>
<%
category.MoveNext
Loop
%>

How to access prev or next array at foreach blade laravel

I currently develop a blade View that will loop an array from Controller.
I just create a table that have an aspects, detail aspects, current status, and remark. So, I want loop (with foreach) at my blade view, then at my array there will be a condition that aspects have same value in next row.
For table example:
Aspects | Detail Aspects | Current Status | Remark
Curriculum | 1 | Good | Good
Curriculum | 2 | Good | Good
Curriculum | 3 | Good | Good
Teaching | 4 | Good | Good
So for the table, I want to check if prev.Aspect == current.Aspect, so I don't need to print it again, or maybe I can rowspan that .
I already using $index at my foreach, but I only can print it as number, not accessing my Obj[index] value.
Here my blade code :
<table border='1'>
<tr align='center' class='header'><td>Aspects</td><td>Details</td><td>Current Status</td><td>Remark</td></tr>
#foreach($prAspect as $index => $data)
<tr>
<td>{{$data->praDesc}}</td>
<td>{{$data->prsDesc}}</td>
<td>{{$data->currentStatus}}</td>
<td>{{$data->remark}}</td>
</tr>
#endforeach
</table>
You could use for loop instead :
#for ($i = 0; $i < count($prAspect); $i++)
// use $i as index
// use $prAspect[$i]
#endfor
Add ->toArray() to your query builder when you fetch the data. This will help your purpose in this case to access the items as an array for easier comparison.
<table border='1'>
<tr align='center' class='header'><td>Aspects</td><td>Details</td><td>Current Status</td><td>Remark</td></tr>
#foreach($prAspect as $index => $data)
<tr>
<td>{{$data['praDesc']}}</td>
<td>{{$data['prsDesc']}}</td>
<td>{{$data['currentStatus']}}</td>
<td>{{$data['remark']}}</td>
</tr>
#endforeach
</table>
Try it might help
#foreach($prAspect as $index => $data)
<tr>
<td>{{!$loop->first ? $prAspect[$index- 1]->praDesc : $data->praDesc}}</td>
<td>{{!$loop->first ? $prAspect[$index - 1]->prsDesc : $data->prsDesc }}</td>
<td>{{!$loop->first ? $prAspect[$index- 1]->currentStatus : $data->currentStatus }}</td>
<td>{{!$loop->first ? $prAspect[$index- 1]->remark : $data->remark }}</td>
</tr>
#endforeach

Using Html Agility Pack to capture inner text from a specific node

I am trying to grab the text "Record No: 1" and the two dates from the following html snippet:
<table class="Report">
<tbody>
<tr>
<td>
<font><b>Record No: 1</b><br>
<i>Original Date</i>: 12/16/2011<br>
<i>Original Entered Date</i>: 12/16/2011
<br>
<br>
</font>
</td>
</tr>
</tbody>
<table>
Using HTMLAgilityPack and the following code I've been able to get the record number but am not sure how to grab the dates.
var recordNum =report.Descendants()
.Where(a=>a.InnerText.Contains("Record No:"))
.Where(a => a.Name == "#text")
.First().InnerText;
Somehow I need to be able to grab the text following the "Original Date" node.
Somehow I need to be able to grab the text following the "Original Date" node.
You can use the following XPath to select text nodes located after i element where inner text equals 'Original Date' :
//i[.='Original Date']/following-sibling::text()
Use the XPath as follow, for example :
var doc = new HtmlDocument();
....
var xpath = "//i[.='Original Date']/following-sibling::text()";
var result = doc.DocumentNode.SelectSingleNode(xpath);
Console.WriteLine(result.InnerText);
Demo
output :
: 12/16/2011

How to iterate visible rows alone using UFT

when i iterate this below webtable,i am getting row count as 3(with hidden row).
but i can see only 2 rows in my application.
i can get row count with help of descriptive programming,but i want to iterate only the rows which are visible.
<table>
<tbody>
<tr class="show">Name</tr>
<tr class="hide">Ticket</tr>
<tr class="show">city</tr>
</tbody>
</table>
i have tried this below code,but its displays hidden row text as well,
for i=1 to rowcount
print oWebtable.getcelldata(i,2)
next
Actual Output-
Name,
Ticket,
city
expecting output-
Name,
city
UFT has no way knowledge of your show/hide class names. If you want to filter out some rows you need to do it yourself.
Set desc = Description.Create()
desc("html tag").Value = "TR"
desc("class").Value = "show"
Set cells = oWebtable.ChildObjects(desc)
Print "Count: " & cells.Count
For i = 0 To cells.Count - 1
Print i & ": " & cells(i).GetROProperty("inner_text")
Next
Note that I had to add TD elements to your table in order for this to work since it's invalid HTML to have text in a TR element.

DAX previous non empty day

Sorry if I missed similar question/answer.
Basically I am trying to do a day to day comparison in DAX, but cannot find a good way to get the measure for previous non empty day.
I tried PREVIOUSDAY function, but when there is a gap in days, for instance, if there is no sale on Sat & Sun, the result is not what I need
PreviousAmount = CALCULATE([Total $ Amount], PREVIOUSDAY('Fact'[Date]))
What I can think of is to add a helper column in the date dimension to indicate previous non empty date (i.e. if the date is Monday, then previous non empty date will be previous Friday). Then I can use CALCULATE function and filter by the non empty date.
But instead of doing that, is there any way to do the calculation on the fly? Thanks in advance.
Below table should reflect what I want to achieve:
<table border="1">
<th>Date</th><th>Amount</th><th>What I got</th><th>What I hope</th>
<tr>
<td>01/07/2016</td>
<td>7983</td>
<td></td>
<td></td>
</tr>
<tr>
<td>04/07/2016</td>
<td>15933</td>
<td></td>
<td>7983</td>
</tr>
<tr>
<tr>
<td>05/07/2016</td>
<td>38591</td>
<td>15933</td>
<td>15933</td>
</tr>
<tr>
<td>06/07/2016</td>
<td>7859</td>
<td>38591</td>
<td>38591</td>
</tr>
<tr>
<td>07/07/2016</td>
<td>3252</td>
<td>7859</td>
<td>7859</td>
</tr>
<tr>
<td>07/07/2016</td>
<td>9474</td>
<td>3252</td>
<td>3252</td>
</tr>
</table>
It may not be the neatest but you can create a calculated column to store the previous day value
PreviousDate =
CALCULATE (
MAX ( [Date] ),
FILTER ( AmountTable, AmountTable[Date] < EARLIER ( AmountTable[Date] ) )
)
and then create a new calculated column for the amount for that previous day
=
CALCULATE (
SUM ( [Amount] ),
FILTER (
ALL ( AmountTable ),
AmountTable[Date] = EARLIER ( AmountTable[PreviousDate] )
)
)

Resources