I'm using Mottie's tablesorter plugin with the Math extension. I have a conditionally formatted table - the categories of conditional formatting are indicated in a data-color attribute on the data cell.
In the footer, I have several rows that summarize the values of the conditional formatting. The footer cells are decorated with data-math-filter="[data-color='color1']".
<table>
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
</tr>
</thead>
<tbody>
<tr>
<td data-color='red' style='background-color:red'>
3
</td>
<td data-color='blue' style='background-color:blue'>
7
</td>
</tr>
<tr>
<td data-color='green' style='background-color:green'>
6
</td>
<td data-color='red' style='background-color:red'>
4
</td>
</tbody>
<tfoot>
<tr>
<td data-math-filter='[data-color="red"]' data-math='col-sum'></td>
<td data-math-filter='[data-color="red"]' data-math='col-sum'></td>
</tr>
<tr>
<td data-math-filter='[data-color="green"]' data-math='col-sum'></td>
<td data-math-filter='[data-color="green"]' data-math='col-sum'></td>
</tr>
<tr>
<td data-math-filter='[data-color="blue"]' data-math='col-sum'></td>
<td data-math-filter='[data-color="blue"]' data-math='col-sum'></td>
</tr>
</tfoot>
</table>
My reading of the docs leads me to believe that the math function will filter for the data-elements - but it doesn't seem to work. I've tried a bunch of different CSS filters - nothing seems to work.
What am I doing wrong?
I am converting a table to pdf, if I put the pdf into portrait then the PDF gets generated with no issues.
However the table is quite wide so I need to switch it to landscape, as soon as I do I receive the following error:
TypeError: cell is undefined[Learn More] jspdf.plugin.autotable.js:690:17
Sadly I can't share the table as it is confidential work (hence the local pdf creation) but here is the script I am using.
$('#btnExportPDF').on('click', function(e){
e.preventDefault();
let source = document.getElementById('iframeReport').contentWindow.document.getElementById('tblReport');
$('#divHiddenTable').html(source.outerHTML);
console.log(source);
let doc = new jsPDF({format: 'a4', unit: 'pt', orientation: 'l'});//change l to p and it works
console.log('PDF Obj');
doc.autoTable({html: '#tblReport'});
console.log('PDF autoTable');
doc.save("RegionalDirectorsWriteOffReviewExport.pdf");
console.log('PDF save');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.debug.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf-autotable/3.0.9/jspdf.plugin.autotable.js"></script>
After some more investigation, it appears that if I remove the OFFICE 3 section from the table below it works, but with it in it doesn't.
<table class="table table-striped" id="tblReport">
<thead>
<tr>
<th>Client
Code</th>
<th>Client
Partner</th>
<th>Client
Name</th>
<th> </th>
<th align="center">Billed</th>
<th align="center">WIP
W/O</th>
<th align="center">Profit/
Loss</th>
<th>Recovery</th>
<th>Comments</th>
</tr>
</thead>
<tbody>
<tr class="OfficeHeader">
<th colspan="9">City 1</th>
</tr>
<tr>
<td>123456</td>
<td>NAME</td>
<td>COMPANY </td>
<td>WHOAMI</td>
<td class="text-right">2,069.58</td>
<td class="text-right">4,609.66</td>
<td class="text-right">-2,540.08</td>
<td class="text-right">44.89</td>
<td></td>
</tr>
<tr>
<td>45384</td>
<td>NAME</td>
<td>COMPANY 2</td>
<td>WHOAMI</td>
<td class="text-right">195.00</td>
<td class="text-right">4,559.74</td>
<td class="text-right">-4,364.74</td>
<td class="text-right">4.27</td>
<td></td>
</tr>
<tr>
<td>852136</td>
<td>NAME</td>
<td>COMPANY 3</td>
<td> </td>
<td class="text-right">600.00</td>
<td class="text-right">3,109.00</td>
<td class="text-right">-2,509.00</td>
<td class="text-right">19.29</td>
<td></td>
</tr>
<tr>
<td>111</td>
<td>NAME</td>
<td>COMPANY 4</td>
<td>WHOAMI</td>
<td class="text-right">0.00</td>
<td class="text-right">1,677.50</td>
<td class="text-right">-1,677.50</td>
<td class="text-right">0.00</td>
<td></td>
</tr>
<tr>
<td>123654</td>
<td>NAME</td>
<td>COMPANY</td>
<td>WHOAMI</td>
<td class="text-right">0.00</td>
<td class="text-right">1,169.75</td>
<td class="text-right">-1,169.75</td>
<td class="text-right">0.00</td>
<td></td>
</tr>
<tr class="OfficeFooter">
<td colspan="4" class="text-right">Office Totals</td>
<td class="text-right"><div class="double-border">2,864.58</div></td>
<td class="text-right"><div class="double-border">15,125.65</div></td>
<td class="text-right"><div class="double-border">-12,261.07</div></td>
<td colspan="2"><div class="pagebreak"> </div></td>
</tr>
<tr class="OfficeHeader">
<th colspan="9">City 2</th>
</tr>
<tr>
<td>A-569</td>
<td>NAME</td>
<td>COMPANY </td>
<td>WHOIZYOU</td>
<td class="text-right">2,175.00</td>
<td class="text-right">4,361.72</td>
<td class="text-right">-2,186.72</td>
<td class="text-right">49.86</td>
<td>Overrun against a thing that we don't know so can't put here</td>
</tr>
<tr>
<td>D/6666</td>
<td>NAME</td>
<td>COMPANY</td>
<td>WHOIZTHIS</td>
<td class="text-right">1,300.00</td>
<td class="text-right">2,371.01</td>
<td class="text-right">-1,071.01</td>
<td class="text-right">54.82</td>
<td>Taken on from previous prtner and manager</td>
</tr>
<tr class="OfficeFooter">
<td colspan="4" class="text-right">Office Totals</td>
<td class="text-right"><div class="double-border">3,475.00</div></td>
<td class="text-right"><div class="double-border">6,732.73</div></td>
<td class="text-right"><div class="double-border">-3,257.73</div></td>
<td colspan="2"><div class="pagebreak"> </div></td>
</tr>
<tr class="OfficeHeader">
<th colspan="9">OFFICE 3</th>
</tr>
<tr>
<td>GFDGDFGF</td>
<td>NAME</td>
<td>COMPANY </td>
<td>WHO</td>
<td class="text-right">2,910.00</td>
<td class="text-right">8,385.21</td>
<td class="text-right">-5,475.21</td>
<td class="text-right">34.70</td>
<td></td>
</tr>
<tr>
<td>KJHKJHKJ</td>
<td>NAME</td>
<td>COMPANY Limited </td>
<td>WHO</td>
<td class="text-right">2,310.00</td>
<td class="text-right">4,733.76</td>
<td class="text-right">-2,423.76</td>
<td class="text-right">48.79</td>
<td></td>
</tr>
<tr>
<td>OIOUIO</td>
<td>NAM,E</td>
<td>COMPANY</td>
<td>WHOZ</td>
<td class="text-right">0.00</td>
<td class="text-right">2,110.25</td>
<td class="text-right">-2,110.25</td>
<td class="text-right">0.00</td>
<td></td>
</tr>
<tr class="OfficeFooter">
<td colspan="4" class="text-right">Office Totals</td>
<td class="text-right"><div class="double-border">5,220.00</div></td>
<td class="text-right"><div class="double-border">15,229.22</div></td>
<td class="text-right"><div class="double-border">-10,009.22</div></td>
<td colspan="2"><div class="pagebreak"> </div></td>
</tr>
</tbody>
<tfoot>
<tr style="height: 2px !important; overflow: hidden !important;">
<td colspan="4"><div style="line-height: 2px !important; height: 2px !important; font-size: 2px !important; overflow: hidden; !important;"> </div></td>
<td colspan="3"><div style="line-height: 2px !important; height: 2px !important; font-size: 2px !important; background-color: #e7ebee; overflow: hidden !important;"> </div></td>
<td colspan="2"><div style="line-height: 2px !important; height: 2px !important; font-size: 2px !important; overflow: hidden; !important;"> </div></td>
</tr>
<tr>
<td colspan="4" class="text-right">AVG</td>
<td class="text-right">1,319.98</td>
<td class="text-right">3,526.59</td>
<td class="text-right">-2,206.61</td>
<td colspan="2"> </td>
</tr>
<tr>
<td colspan="4" class="text-right">Totals</td>
<td class="text-right"><div class="double-border">27,719.58</div></td>
<td class="text-right"><div class="double-border">74,058.42</div></td>
<td class="text-right"><div class="double-border">-46,338.84</div></td>
<td colspan="2"> </td>
</tr>
</tfoot>
</table>
example JSFiddle https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.2.1/css/bootstrap.css
This is what my highchart looks like atm
I kinda want the chart to be on the right side while the table to be on the left
this is my html:
<div id="words" style="width:70%;float:left;">
<table border="1" class="highchart" data-graph-container-before="1" data-graph-type="column">
<thead>
<tr>
<th>Word</th>
<th>Count</th>
</tr>
</thead>
<tbody>
<tr>
<td>icon</td>
<td>12</td>
</tr>
<tr>
<td>text</td>
<td>12</td>
</tr>
<tr>
<td>your</td>
<td>9</td>
</tr>
<tr>
<td>post</td>
<td>6</td>
</tr>
<tr>
<td>document</td>
<td>5</td>
</tr>
<tr>
<td>with</td>
<td>5</td>
</tr>
<tr>
<td>parentNode</td>
<td>4</td>
</tr>
<tr>
<td>email</td>
<td>4</td>
</tr>
<tr>
<td>com"</td>
<td>4</td>
</tr>
<tr>
<td>googletag</td>
<td>3</td>
</tr>
</tbody>
</table>
What should i do to achieve such output?
If you can change HTML, then simply put table before Highcharts container and set proper styles (float, width). For example you can also use two divs: http://jsfiddle.net/68qdew8g/
<div style="float: left; width: 30%;">
<table border="1" class="highchart" data-graph-container-before="1" data-graph-type="column">
...
</table>
</div>
<div id="words" style="width:70%;float:left;"></div>
I'm trying to loop through the elements in each but am having issues with the inner loop below. It appears to me the xpath pattern '*/td' is not returning any results. I'm expecting to see the data inside the tags printed to stdout. I'm using nokogiri.
I'm pasting this into my rails console:
require 'nokogiri'
f = File.open("public/index.html")
doc = Nokogiri::HTML(f)
f.close
doc.xpath('//*[#id="WhoIsOnDutyTableLevel4"]/tbody/tr').each do |row|
puts "row= " + row.to_s
row.xpath('*/td').each do |td|
puts "td= " + td
end
end
And here's the output from the console:
row= <tr id="208894">
<td headers="WhoIsOnDutyTableLevel1:header:1">User 1</td>
<td headers="WhoIsOnDutyTableLevel1:header:2">PERSON</td>
<td headers="WhoIsOnDutyTableLevel1:header:3">0</td>
</tr>
row= <tr id="207792">
<td headers="WhoIsOnDutyTableLevel1:header:1">User 2</td>
<td headers="WhoIsOnDutyTableLevel1:header:2">PERSON</td>
<td headers="WhoIsOnDutyTableLevel1:header:3">5</td>
</tr>
=> 0
Here's the html I'm parsing:
<table class="duty-report-level1" id="WhoIsOnDutyTableLevel1">
<caption></caption>
<thead>
<tr>
<th id="WhoIsOnDutyTableLevel1:header:1" class="duty-report-lt-header">c</th>
</tr>
</thead>
<tfoot></tfoot>
<tbody>
<tr>
<td headers="WhoIsOnDutyTableLevel1:header:1">
<table class="duty-report-level2" id="WhoIsOnDutyTableLevel2">
<caption></caption>
<thead>
<tr>
<th id="WhoIsOnDutyTableLevel1:header:1">Group Name</th><th id="WhoIsOnDutyTableLevel1:header:2">Group Time Zone</th><th id="WhoIsOnDutyTableLevel1:header:3">Default Devices</th><th id="WhoIsOnDutyTableLevel1:header:4">Supervisors</th>
</tr>
</thead>
<tfoot></tfoot>
<tbody>
<tr>
<td headers="WhoIsOnDutyTableLevel1:header:1">Team 1</td><td headers="WhoIsOnDutyTableLevel1:header:2" class="centered-text">US/Pacific</td><td headers="WhoIsOnDutyTableLevel1:header:3" class="centered-text"><img src="/static/images/icon_boolean_false.png" alt="No" border="0"></td><td headers="WhoIsOnDutyTableLevel1:header:4">
<values>
</values>Mgr 1
<br>
</td>
</tr>
<tr>
<td headers="WhoIsOnDutyTableLevel1:header:1" class="no-padding" colspan="4">
<table class="duty-report-level3" id="WhoIsOnDutyTableLevel3">
<caption></caption>
<thead>
<tr>
<th id="WhoIsOnDutyTableLevel1:header:1" class="th-left">a</th><th id="WhoIsOnDutyTableLevel1:header:2" class="">b</th>
</tr>
</thead>
<tfoot></tfoot>
<tbody>
<tr>
<td headers="WhoIsOnDutyTableLevel1:header:1" class="no-padding" colspan="2">
<table class="duty-report-level4" id="WhoIsOnDutyTableLevel4">
<caption></caption>
<thead>
<tr>
<th id="WhoIsOnDutyTableLevel1:header:1">Recipient</th><th id="WhoIsOnDutyTableLevel1:header:2">Category</th><th id="WhoIsOnDutyTableLevel1:header:3">Escalation</th>
</tr>
</thead>
<tfoot></tfoot>
<tbody>
<tr id="208894">
<td headers="WhoIsOnDutyTableLevel1:header:1">User 1</td><td headers="WhoIsOnDutyTableLevel1:header:2">PERSON</td><td headers="WhoIsOnDutyTableLevel1:header:3">0</td>
</tr>
<tr id="207792">
<td headers="WhoIsOnDutyTableLevel1:header:1">User 2</td><td headers="WhoIsOnDutyTableLevel1:header:2">PERSON</td><td headers="WhoIsOnDutyTableLevel1:header:3">5</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
You need a minor change to your XPath:
doc.xpath('//*[#id="WhoIsOnDutyTableLevel4"]/tbody/tr').each do |row|
# puts "row= " + row.to_s
row.xpath('./td').each do |td|
puts "td= " + td.text
end
end
Which outputs:
td= User 1
td= PERSON
td= 0
td= User 2
td= PERSON
td= 5
Using ./td as the XPath for td basically means "from this point look down one".
Personally, unless you absolutely need XPath, I recommend using CSS accessors. They are more readable, and often much more simple:
doc.search('#WhoIsOnDutyTableLevel4 tbody tr').each do |row|
row.search('td').each do |td|
puts "td= " + td.text
end
end
I recommend using search instead of css or xpath and at instead of at_css or at_xpath. There is no real magic going on when you choose one over the other and you only have to remember two different methods.
The XPath expression in the inner loop is evaluated relative to each tr, so you want to use td (which selects children td elements of the context tr) and not */td (which selects grandchildren td elements).
Full code:
doc.xpath('//*[#id="WhoIsOnDutyTableLevel4"]/tbody/tr').each do |row|
puts "row= " + row.to_s
row.xpath('td').each do |td|
puts "td= " + td
end
end
I'm receiving an error when trying to select a node with css value of "WhoIsOnDutyTableLevel1:header:2" using nokogiri. I'm assuming nokogiri just can't handle two colons. What are my options? I can't change the structure of the html.
Here's the html:
<html lang="en"><head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
<link rel="stylesheet" type="text/css" href="stylesheets/forms.css">
<style type="text/css" media="screen" title="AlarmPoint">
#import "stylesheets/AlarmPoint.css";
</style>
</head>
<body><table id="WhoIsOnDutyTableLevel1" class="duty-report-level1">
<caption></caption>
<thead>
<tr>
<th id="WhoIsOnDutyTableLevel1:header:1" class="duty-report-lt-header">Who's on duty for:
January 06, 2012 00:00 -0800</th>
</tr>
</thead>
<tfoot></tfoot>
<tbody>
<tr>
<td headers="WhoIsOnDutyTableLevel1:header:1">
<table id="WhoIsOnDutyTableLevel2" class="duty-report-level2">
<caption></caption>
<thead>
<tr>
<th id="WhoIsOnDutyTableLevel1:header:1">Group Name</th><th id="WhoIsOnDutyTableLevel1:header:2">Group Time Zone</th><th id="WhoIsOnDutyTableLevel1:header:3">Default Devices</th><th id="WhoIsOnDutyTableLevel1:header:4">Supervisors</th>
</tr>
</thead>
<tfoot></tfoot>
<tbody>
<tr>
<td headers="WhoIsOnDutyTableLevel1:header:1"><a id="Support" href="/alarmpoint/GroupDetails.do;jsessionid=7pj06dj6krfs?_data=TJZuNquzHUiPj8lqyud7XvypLHHjUnT5bHn7hwtTf9Ei0C2PJ8QYcKIy8OkorCWT8HDTAzkon1ls%0D%0AefuHC1N%2F0SLQLY8nxBhwesdd7Zeg6NzvCfuzRqLg5g%3D%3D" name="Support" class="details">Support</a></td><td headers="WhoIsOnDutyTableLevel1:header:2" class="centered-text">US/Pacific</td><td headers="WhoIsOnDutyTableLevel1:header:3" class="centered-text"><img border="0" src="/static/images/icon_boolean_false.png" alt="No"></td><td headers="WhoIsOnDutyTableLevel1:header:4">
<values>
</values><a id="mgr1" href="/alarmpoint/UserDevices.do;jsessionid=7pj06dj6krfs?_data=KpBkJeR08z4qZ%2FFdHH4hUAixAYz%2BqH6ZPkanPQ24VqQFpjRFPQiWigQHttJBTMFaCLEBjP6ofpk%2B%0D%0ARqc9DbhWpI1nHAqm8ex%2BxOmu7xYUNxRSU0XUo1xoRw%3D%3D" name="mgr1" class="details">Manager 1</a>
</td>
</tr>
<tr>
<td headers="WhoIsOnDutyTableLevel1:header:1" colspan="4" class="no-padding">
<table id="WhoIsOnDutyTableLevel3" class="duty-report-level3">
<caption></caption>
<thead>
<tr>
<th id="WhoIsOnDutyTableLevel1:header:1" class="th-left">Blah_Blah1</th><th id="WhoIsOnDutyTableLevel1:header:2" class="">08:00 - 17:00 TU WE TH FR </th>
</tr>
</thead>
<tfoot></tfoot>
<tbody>
<tr>
<td headers="WhoIsOnDutyTableLevel1:header:1" colspan="2" class="no-padding">
<table id="WhoIsOnDutyTableLevel4" class="duty-report-level4">
<caption></caption>
<thead>
<tr>
<th id="WhoIsOnDutyTableLevel1:header:1">Recipient</th><th id="WhoIsOnDutyTableLevel1:header:2">Category</th><th id="WhoIsOnDutyTableLevel1:header:3">Escalation</th>
</tr>
</thead>
<tfoot></tfoot>
<tbody>
<tr id="205414">
<td headers="WhoIsOnDutyTableLevel1:header:1"><a id="user0" href="/alarmpoint/UserDevices.do;jsessionid=7pj06dj6krfs?_data=KpBkJeR08z6oL%2BaI47zI4gixAYz%2BqH6ZPkanPQ24VqQFpjRFPQiWigQHttJBTMFaCLEBjP6ofpk%2B%0D%0ARqc9DbhWpI1nHAqm8ex%2BxOmu7xYUNxRSU0XUo1xoRw%3D%3D" name="user0" class="details">User 0</a></td><td headers="WhoIsOnDutyTableLevel1:header:2">PERSON</td><td headers="WhoIsOnDutyTableLevel1:header:3">0</td>
</tr>
<tr id="207569">
<td headers="WhoIsOnDutyTableLevel1:header:1"><a id="user1" href="/alarmpoint/UserDevices.do;jsessionid=7pj06dj6krfs?_data=KpBkJeR08z4qZ%2FFdHH4hUAixAYz%2BqH6ZPkanPQ24VqQFpjRFPQiWigQHttJBTMFaCLEBjP6ofpk%2B%0D%0ARqc9DbhWpI1nHAqm8ex%2BxOmu7xYUNxRSU0XUo1xoRw%3D%3D" name="user1" class="details">User 1</a></td><td headers="WhoIsOnDutyTableLevel1:header:2">PERSON</td><td headers="WhoIsOnDutyTableLevel1:header:3">10</td>
</tr>
<tr id="209107">
<td headers="WhoIsOnDutyTableLevel1:header:1"><a id="user2" href="/alarmpoint/UserDevices.do;jsessionid=7pj06dj6krfs?_data=KpBkJeR08z6uKpyoDh%2Fz%2FQixAYz%2BqH6ZPkanPQ24VqQFpjRFPQiWigQHttJBTMFaCLEBjP6ofpk%2B%0D%0ARqc9DbhWpI1nHAqm8ex%2BxOmu7xYUNxRSU0XUo1xoRw%3D%3D" name="uer2" class="details">User 2</a></td><td headers="WhoIsOnDutyTableLevel1:header:2">PERSON</td><td headers="WhoIsOnDutyTableLevel1:header:3">25</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td headers="WhoIsOnDutyTableLevel1:header:1" colspan="4" class="no-padding">
<table id="WhoIsOnDutyTableLevel3" class="duty-report-level3">
<caption></caption>
<thead>
<tr>
<th id="WhoIsOnDutyTableLevel1:header:1" class="th-left">Blah_Blah</th><th id="WhoIsOnDutyTableLevel1:header:2" class="">17:00 Lasting 15:00 WE TH FR </th>
</tr>
</thead>
<tfoot></tfoot>
<tbody>
<tr>
<td headers="WhoIsOnDutyTableLevel1:header:1" colspan="2" class="no-padding">
<table id="WhoIsOnDutyTableLevel4" class="duty-report-level4">
<caption></caption>
<thead>
<tr>
<th id="WhoIsOnDutyTableLevel1:header:1">Recipient</th><th id="WhoIsOnDutyTableLevel1:header:2">Category</th><th id="WhoIsOnDutyTableLevel1:header:3">Escalation</th>
</tr>
</thead>
<tfoot></tfoot>
<tbody>
<tr id="210855">
<td headers="WhoIsOnDutyTableLevel1:header:1"><a id="user0" href="/alarmpoint/UserDevices.do;jsessionid=7pj06dj6krfs?_data=KpBkJeR08z72pjQodq7P5gixAYz%2BqH6ZPkanPQ24VqQFpjRFPQiWigQHttJBTMFaCLEBjP6ofpk%2B%0D%0ARqc9DbhWpI1nHAqm8ex%2BxOmu7xYUNxRSU0XUo1xoRw%3D%3D" name="user0" class="details">User 0</a></td><td headers="WhoIsOnDutyTableLevel1:header:2">PERSON</td><td headers="WhoIsOnDutyTableLevel1:header:3">5</td>
</tr>
<tr id="210529">
<td headers="WhoIsOnDutyTableLevel1:header:1"><a id="user1" href="/alarmpoint/UserDevices.do;jsessionid=7pj06dj6krfs?_data=KpBkJeR08z6r1%2Fmnw2SZ2AixAYz%2BqH6ZPkanPQ24VqQFpjRFPQiWigQHttJBTMFaCLEBjP6ofpk%2B%0D%0ARqc9DbhWpI1nHAqm8ex%2BxOmu7xYUNxRSU0XUo1xoRw%3D%3D" name="user1" class="details">User 1</a></td><td headers="WhoIsOnDutyTableLevel1:header:2">PERSON</td><td headers="WhoIsOnDutyTableLevel1:header:3">10</td>
</tr>
<tr id="210337">
<td headers="WhoIsOnDutyTableLevel1:header:1"><a id="user2" href="/alarmpoint/UserDevices.do;jsessionid=7pj06dj6krfs?_data=KpBkJeR08z6Rwqu8vCtzBAixAYz%2BqH6ZPkanPQ24VqQFpjRFPQiWigQHttJBTMFaCLEBjP6ofpk%2B%0D%0ARqc9DbhWpI1nHAqm8ex%2BxOmu7xYUNxRSU0XUo1xoRw%3D%3D" name="user2" class="details">User 2</a></td><td headers="WhoIsOnDutyTableLevel1:header:2">PERSON</td><td headers="WhoIsOnDutyTableLevel1:header:3">15</td>
</tr>
<tr id="204675">
<td headers="WhoIsOnDutyTableLevel1:header:1"><a id="user3" href="/alarmpoint/UserDevices.do;jsessionid=7pj06dj6krfs?_data=KpBkJeR08z5oj5jdRJbzggixAYz%2BqH6ZPkanPQ24VqQFpjRFPQiWigQHttJBTMFaCLEBjP6ofpk%2B%0D%0ARqc9DbhWpI1nHAqm8ex%2BxOmu7xYUNxRSU0XUo1xoRw%3D%3D" name="user3" class="details">User 3</a></td><td headers="WhoIsOnDutyTableLevel1:header:2">PERSON</td><td headers="WhoIsOnDutyTableLevel1:header:3">20</td>
</tr>
<tr id="205555">
<td headers="WhoIsOnDutyTableLevel1:header:1"><a id="user4" href="/alarmpoint/UserDevices.do;jsessionid=7pj06dj6krfs?_data=KpBkJeR08z4G8e7%2FY9SHyQixAYz%2BqH6ZPkanPQ24VqQFpjRFPQiWigQHttJBTMFaCLEBjP6ofpk%2B%0D%0ARqc9DbhWpI1nHAqm8ex%2BxOmu7xYUNxRSU0XUo1xoRw%3D%3D" name="user4" class="details">User 4</a></td><td headers="WhoIsOnDutyTableLevel1:header:2">PERSON</td><td headers="WhoIsOnDutyTableLevel1:header:3">25</td>
</tr>
<tr id="205004">
<td headers="WhoIsOnDutyTableLevel1:header:1"><a id="user5" href="/alarmpoint/UserDevices.do;jsessionid=7pj06dj6krfs?_data=KpBkJeR08z5XHkcVAMfXqgixAYz%2BqH6ZPkanPQ24VqQFpjRFPQiWigQHttJBTMFaCLEBjP6ofpk%2B%0D%0ARqc9DbhWpI1nHAqm8ex%2BxOmu7xYUNxRSU0XUo1xoRw%3D%3D" name="user5" class="details">User 5</a></td><td headers="WhoIsOnDutyTableLevel1:header:2">PERSON</td><td headers="WhoIsOnDutyTableLevel1:header:3">30</td>
</tr>
<tr id="204718">
<td headers="WhoIsOnDutyTableLevel1:header:1"><a id="user6" href="/alarmpoint/GroupDetails.do;jsessionid=7pj06dj6krfs?_data=TJZuNquzHUiUNEK29yovHscXndexl2jCbHn7hwtTf9Ei0C2PJ8QYcKIy8OkorCWT8HDTAzkon1ls%0D%0AefuHC1N%2F0SLQLY8nxBhwesdd7Zeg6NzvCfuzRqLg5g%3D%3D" name="user6" class="details">User 6</a></td><td headers="WhoIsOnDutyTableLevel1:header:2">GROUP</td><td headers="WhoIsOnDutyTableLevel1:header:3">35</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</body></html>
I'm running this in my rails console:
>> onDuty_userList = doc.at_xpath('//*[#id="WhoIsOnDutyTableLevel4"]/tbody/tr')
=> #<Nokogiri::XML::Element:0x1b83804 name="tr" attributes=[#<Nokogiri::XML::Attr:0x1b83764 name="id" value="208894">] children=[#<Nokogiri::XML::Element:0x1b83174 name="td" attributes=[#<Nokogiri::XML::Attr:0x1b83110 name="headers" value="WhoIsOnDutyTableLevel1:header:1">] children=[#<Nokogiri::XML::Element:0x1b82b70 name="a" attributes=[#<Nokogiri::XML::Attr:0x1b82aa8 name="href" value="/alarmpoint/UserDevices.do;jsessionid=3pz7t91kle3?_data=KpBkJeR08z6mdgIY4sPrzAixAYz%2BqH6ZPkanPQ24VqQFpjRFPQiWigQHttJBTMFaCLEBjP6ofpk%2B%0D%0ARqc9DbhWpI1nHAqm8ex%2BxOmu7xYUNxRSU0XUo1xoRw%3D%3D">, #<Nokogiri::XML::Attr:0x1b82a94 name="name" value="xxx">, #<Nokogiri::XML::Attr:0x1b82a80 name="id" value="xxx">, #<Nokogiri::XML::Attr:0x1b82a6c name="class" value="details">] children=[#<Nokogiri::XML::Text:0x1b7b438 "\r\n xxx, xxx (xxx)\r\n ">]>]>, #<Nokogiri::XML::Element:0x1b7b104 name="td" attributes=[#<Nokogiri::XML::Attr:0x1b7b0a0 name="headers" value="WhoIsOnDutyTableLevel1:header:2">] children=[#<Nokogiri::XML::Text:0x1b7aba0 "PERSON">]>, #<Nokogiri::XML::Element:0x1b7a984 name="td" attributes=[#<Nokogiri::XML::Attr:0x1b7a90c name="headers" value="WhoIsOnDutyTableLevel1:header:3">] children=[#<Nokogiri::XML::Text:0x1b7a420 "0">]>, #<Nokogiri::XML::Text:0x1b7a1f0 "\r\n">]>
When I try to select with css value:
>> onDuty_userList.css('WhoIsOnDutyTableLevel1:header:2')
Nokogiri::CSS::SyntaxError: unexpected '2' after ':'
from /home/dan/.rvm/gems/ruby-1.9.2-p290#apraper/gems/nokogiri-1.5.0/lib/nokogiri/css/parser_extras.rb:87:in `on_error'
from /home/dan/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/racc/parser.rb:99:in `_racc_do_parse_c'
from /home/dan/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/racc/parser.rb:99:in `do_parse'
from /home/dan/.rvm/gems/ruby-1.9.2-p290#apraper/gems/nokogiri-1.5.0/lib/nokogiri/css/parser_extras.rb:62:in `parse'
from /home/dan/.rvm/gems/ruby-1.9.2-p290#apraper/gems/nokogiri-1.5.0/lib/nokogiri/css/parser_extras.rb:79:in `xpath_for'
from /home/dan/.rvm/gems/ruby-1.9.2-p290#apraper/gems/nokogiri-1.5.0/lib/nokogiri/css.rb:23:in `xpath_for'
from /home/dan/.rvm/gems/ruby-1.9.2-p290#apraper/gems/nokogiri-1.5.0/lib/nokogiri/xml/node.rb:211:in `block in css'
from /home/dan/.rvm/gems/ruby-1.9.2-p290#apraper/gems/nokogiri-1.5.0/lib/nokogiri/xml/node.rb:210:in `map'
from /home/dan/.rvm/gems/ruby-1.9.2-p290#apraper/gems/nokogiri-1.5.0/lib/nokogiri/xml/node.rb:210:in `css'
from (irb):129
from /home/dan/.rvm/rubies/ruby-1.9.2-p290/bin/irb:16:in `<main>'
You need to preface the id with a #.
This should work:
doc.css('#WhoIsOnDutyTableLevel1:header:2')