How to select all cells <th> and <td> alike - css

Pardon if this is very basic. I have been trying to traverse each cell including header cells in an array of rows. Is there an OR operator I can use in the Nokogiri CSS selector?
thang= Nokogiri::HTML(IO.read "|cat page.html").css('table[#id="costbasisTable"] tr')
Correctly fetches all rows including a header row (which repeats on subsequent pages):
thang[0].inner_html
=> <th class="tLeft"></th><th>cellA2</th><th>cellA3data</th>
thang[1].inner_html
=> <td>cellB1</td><td>cellB2</td><td>cellB3data</td>
The trouble is with the following, which may return blank if that row contains only th's not td's:
N=0
thang[N].css("td").map{|c| c.text.strip.gsub(/\t.*/,"").delete ",".tr("&/|:;\n","_")}.to_a
What parameter to .css(...) will mean "match any <td> OR <th> cell"?
Is this possible/better done with .xpath() instead for these Nokogiri XML Elements?

You want to use either of the following:
# thang[n] is a Nokogiri <tr> node
cells = thang[n].css('th,td')
cells = thang[n].xpath('./th | ./td')
Note that the CSS version will match any embedded tables (if you had such a horror) while the XPath version will only match direct children of the row.

Related

Robot Framework testing that defined headers in data-table are correct

Im having problem while testing that correct values are present inside data-table element. Im using Selenium2Library and Robot Framework 3.0 version.
Im using this code to check the values inside element
: FOR ${item} IN #{elements} INFO console=yes
\ Wait Until Keyword Succeeds 10 1 Element Should Be Visible
//th[contains(text(),"${item}")] Header not found: ${item}
#{elements} is just a list of column values. It find first two column values and the last value fine when there is no more than one space between the column value. Other column values has spaces and '-' marks. I tried copying the direct value from Developer Console but it didn't help.
Element structure is:
<table class="data-table">
<thead><tr class="odd"><th class="top-left" id="col1">Number-one</th>
<th id="col2">Second-number-column</th>
<th id="col3">Temporary number y-identification</th>
<th id="col4">Temporary numbertwo identification</th>
<th id="col5">Temporary numberthree identification</th>
<th class="top-right" id="col5">Number four</th>
</tr>
</thead>
</table>
Cant put the real column data there but its constructed like that. Problematic values are:
<th id="col3">Temporary number y-identification</th>
<th id="col4">Temporary numbertwo identification</th>
<th id="col5">Temporary numberthree identification</th>
Try normalizing by space in xpath,
: FOR ${item} IN #{elements} INFO console=yes
\ Wait Until Keyword Succeeds 10 1 Element Should Be Visible
//th[contains(normalize-space(text()),"${item}")] Header not found: ${item}

How can you get a dynamically named variable in handlebars?

I am trying to output a table using handlebars.
Right now it loops through the each row, and then through each column, but how can I grab the data from the row based on {{col.name}}?
See here, I need to get COLUMNNAME from {{col.name}}
{{#rows as |row|}}
<tr>
{{#../cols as |col|}}
<td>{{row.COLUMNNAME}}</td>
{{/../cols}}
</tr>
{{/rows}}
In js this would be like row[index][col.name];
Any idea for solutions?
Found the answer, it's the lookup tag.
{{lookup row col.name}}
is equal to
row[col.name]

Using str_match in stringr

I have many text files. In each text file, there is a section of interest (below):
<tr>
<td ><b>发起时间</b></td>
<td colspan="2" style="text-align: left">2015-04-08</td>
<td style="width: 25%;"><b>回报机制</b></td>
<td colspan="2" style="text-align: left">使用者付费</td>
</tr>
The information that varies across files is the date only. In this case, the date is 2015-04-08.
I want to extract the date. I am an R user, and I normally would use str_match from the stringr package. I would indicate the following as the start of the string:
<td ><b>发起时间</b></td>
<td colspan="2" style="text-align: left">
However, I am not sure what to do given that this string is spread over two lines. What can I do? (It also contains Chinese characters, but that's a separate issue)
But I'm not sure how to do so, given that
Doing it with Regex
It's not advisable to use a regex to parse HTML due to all the possible obscure edge cases that can crop up, but it seems that you have some control over the HTML so you should able to avoid many of the edge cases the regex police cry about.
Proposed solution with Regex
Can you use the \s+ where the carriage return and new line would be. The resulting regex would look like this:
<td ><b>发起时间<\/b><\/td>\s+<td colspan="2" style="text-align: left">([0-9]{4}-[0-9]{2}-[0-9]{2})<\/td>
** To see the image better, simply right click the image and select view in new window
And based on your sample text. The first capture group would then contain the string of characters that resembled the date. It should be noted that the regex is not actually validating the date, it's just matching the format.
Explained
The \s+ regex will do the following:
\s matches any white space character
+ allows the preceeding regex to match 1 or more times
Since we know there will be a carriage return, new line, and what appears to be a tab or multiple spaces, then all of those will be matched. However if these whitespace characters are optional in your source files, then you could use the \s*. In this case the * will match zero or more whitespace characters.
Example
Please see this live example

AngularJS Multiple class using expression

I have a table where I need to apply two different classes, using expressions.
1st class is applied based on following expression.
{'Up':'class-up', 'Down':'class-down'}[a.status]
and 2nd class is applied based on bold: !a.read
The classes here are class-up, class-down, bold.
So how should be the expression framed? I tried:
<tr ng-repeat="a in all" ng-class="{{'Up':'class-up', 'Down':'class-down'}[a.status],bold: !a.read}">
<tr ng-repeat="a in all" ng-class="{'Up':'class-up', 'Down':'class-down'}[a.status],bold: !a.read">
But I keep getting errors in console. What is the correct format to apply these classes based on the given expressions
With the clarification from your comment:
<tr ng-repeat="a in all" ng-class="{'class-up': a.status=='up', 'class-down': a.status=='down', 'bold': !a.read}">hello world</tr>

Tal condition always evaluates to false

I'm using plone and trying to display a form result in a page template.
I'm trying to filter some database results using tal:condition with a python expression but it always evaluates to false.
The code looks like this:
<tr tal:repeat="result view/results">
<td> <span tal:condition="python:view.teams[0]==result.team_id" tal:replace="result/position">Position</span></td>
<td> <span tal:condition="python:view.teams[1]==result.team_id" tal:replace="result/position">Position</span></td>
</tr>
I want the table cells to be filled with the team position when the team id is matched in the result, but the cells always are empty.
If I remove the tal:condition from the span and replace the tal:replace="result/position" with tal:replace=python:view.teams[0]==result.team_id it prints True or False so I can check that the result is correct.
Can anyone help me about this issue? Why does tal:condition allways evaluate false?
I'd fully expect this to work, so something else must be wrong.
Python expressions such as yours are commonplace; there are several examples on the internet to show they do normally work.
Try further debugging the values with tal:replace="python:repr(view.teams)" and tal:replace="python:repr(result.team_id)" statements and similar to be 100% certain of what your data structures look like.

Resources