Parse an HTML table with Nokogiri in Ruby - html

I have an HTML table that looks like the following:
<table id="TTdata" border="0" cellspacing="0" cellpadding="3" align="center">
<tbody>
<tr class="TTdata_ltblue">
<td class="ctr"><b>#</b></td>
<td class="ctr"><b>YEAR<img src="/images/up.gif"></b></td>
<td class="ctr" title="Player's name."><b>NAME</b></td>
<td class="ctr" title="how many pitches a catcher had a chance/need to frame"><b>FR_CHANCES</b></td>
<td class="ctr" title="the number of strikes the catcher is expected to have received according to RPM"><b>PREDICTED_STRIKES</b></td>
<td class="ctr" title="the number of strikes the catcher actually received"><b>ACTUAL_STRIKES</b></td>
<td class="ctr" title="the difference between actual and predicted strikes received by the catcher"><b>EXTRA_STRIKES</b></td>
<td class="ctr" title="runs RPM credits to the catcher, using the ball-strike context to calculated run value"><b>FR_RUNS_ADDED_BY_COUNT<img src="/images/down.gif"></b></td>
<td class="ctr" title="how many runs RPM would assign using a generic .14 runs available per frame"><b>FR_RUNS_ADDED_BY_CALL</b></td>
<td class="ctr" title="pitches the catcher received that could have resulted in a wild pitch or passed ball; this is when runners are on base or a dropped third strike is possible"><b>BL_CHANCES</b></td>
<td class="ctr"><b>PREDICTED_PBWP</b></td>
<td class="ctr" title="the run value accumulated from preventing wild pitches and passed balls (.28 per PB/WP saved)"><b>BL_RUNS_ADDED</b></td>
<td class="ctr" title="the number of passed balls and wild pitches allowed by the catcher"><b>ACTUAL_PBWP</b></td>
<td class="ctr" title="the difference between actual and predicted passed balls and wild pitches allowed by the catcher
"><b>PBWP_SAVED</b></td>
</tr>
<tr class="TTdata">
<td>1.</td>
<td class="right">2015</td>
<td>Yasmani Grandal</td>
<td class="right">2295</td>
<td class="right">871.5</td>
<td class="right">925</td>
<td class="right">53.5</td>
<td class="right">8.0</td>
<td class="right">8.0</td>
<td class="right">1097</td>
<td class="right">18.0</td>
<td class="right">0.0</td>
<td class="right">18</td>
<td class="right">0.0</td>
</tr>
<tr class="TTdata_ltgrey">
<td>2.</td>
<td class="right">2015</td>
<td>Buster Posey</td>
<td class="right">2601</td>
<td class="right">1,011.4</td>
<td class="right">1,056</td>
<td class="right">44.6</td>
<td class="right">6.6</td>
<td class="right">6.6</td>
<td class="right">1232</td>
<td class="right">10.0</td>
<td class="right">0.0</td>
<td class="right">10</td>
<td class="right">0.0</td>
</tr>
<tr class="TTdata">
<td>3.</td>
<td class="right">2015</td>
<td>Francisco Cervelli</td>
<td class="right">2629</td>
<td class="right">989.0</td>
<td class="right">1,033</td>
<td class="right">44.0</td>
<td class="right">6.5</td>
<td class="right">6.5</td>
<td class="right">1357</td>
<td class="right">14.0</td>
<td class="right">0.0</td>
<td class="right">14</td>
<td class="right">0.0</td>
</tr>
<tr class="TTdata_ltgrey">
<td>4.</td>
<td class="right">2015</td>
<td>Mike Zunino</td>
<td class="right">2828</td>
<td class="right">1,128.8</td>
<td class="right">1,169</td>
<td class="right">40.2</td>
<td class="right">6.0</td>
<td class="right">6.0</td>
<td class="right">1325</td>
<td class="right">19.0</td>
<td class="right">0.0</td>
<td class="right">19</td>
<td class="right">0.0</td>
</tr>
<tr class="TTdata">
<td>5.</td>
<td class="right">2015</td>
<td>Caleb Joseph</td>
<td class="right">2713</td>
<td class="right">993.9</td>
<td class="right">1,031</td>
<td class="right">37.1</td>
<td class="right">5.5</td>
<td class="right">5.5</td>
<td class="right">1315</td>
<td class="right">9.0</td>
<td class="right">0.0</td>
<td class="right">9</td>
<td class="right">0.0</td>
</tr>
<tr class="TTdata_ltgrey">
<td>6.</td>
<td class="right">2015</td>
<td>Chris Iannetta</td>
<td class="right">2158</td>
<td class="right">847.5</td>
<td class="right">884</td>
<td class="right">36.5</td>
<td class="right">5.4</td>
<td class="right">5.4</td>
<td class="right">1078</td>
<td class="right">15.0</td>
<td class="right">0.0</td>
<td class="right">15</td>
<td class="right">0.0</td>
</tr>
<tr class="TTdata">
<td>7.</td>
<td class="right">2015</td>
<td>Jason Castro</td>
<td class="right">2679</td>
<td class="right">1,068.9</td>
<td class="right">1,105</td>
<td class="right">36.1</td>
<td class="right">5.4</td>
<td class="right">5.4</td>
<td class="right">1378</td>
<td class="right">18.0</td>
<td class="right">0.0</td>
<td class="right">18</td>
<td class="right">0.0</td>
</tr>
<tr class="TTdata_ltgrey">
<td>8.</td>
<td class="right">2015</td>
<td>Miguel Montero</td>
<td class="right">1977</td>
<td class="right">785.8</td>
<td class="right">820</td>
<td class="right">34.2</td>
<td class="right">5.1</td>
<td class="right">5.1</td>
<td class="right">972</td>
<td class="right">11.0</td>
<td class="right">0.0</td>
<td class="right">11</td>
<td class="right">0.0</td>
</tr>
<tr class="TTdata">
<td>9.</td>
<td class="right">2015</td>
<td>Martin Maldonado</td>
<td class="right">2343</td>
<td class="right">906.0</td>
<td class="right">940</td>
<td class="right">34.0</td>
<td class="right">5.1</td>
<td class="right">5.1</td>
<td class="right">1193</td>
<td class="right">17.0</td>
<td class="right">0.0</td>
<td class="right">17</td>
<td class="right">0.0</td>
</tr>
<tr class="TTdata_ltgrey">
<td>10.</td>
<td class="right">2015</td>
<td>Tyler Flowers</td>
<td class="right">2191</td>
<td class="right">833.4</td>
<td class="right">865</td>
<td class="right">31.6</td>
<td class="right">4.7</td>
<td class="right">4.7</td>
<td class="right">1305</td>
<td class="right">13.0</td>
<td class="right">0.0</td>
<td class="right">13</td>
<td class="right">0.0</td>
</tr>
<tr class="TTdata">
<td>11.</td>
<td class="right">2015</td>
<td>Rene Rivera</td>
<td class="right">2632</td>
<td class="right">1,043.1</td>
<td class="right">1,070</td>
<td class="right">26.9</td>
<td class="right">4.0</td>
<td class="right">4.0</td>
<td class="right">1331</td>
<td class="right">18.0</td>
<td class="right">0.0</td>
<td class="right">18</td>
<td class="right">0.0</td>
</tr>
<tr class="TTdata_ltgrey">
<td>12.</td>
<td class="right">2015</td>
<td>Russell Martin</td>
<td class="right">2919</td>
<td class="right">1,121.3</td>
<td class="right">1,148</td>
<td class="right">26.7</td>
<td class="right">4.0</td>
<td class="right">4.0</td>
<td class="right">1470</td>
<td class="right">27.0</td>
<td class="right">0.0</td>
<td class="right">27</td>
<td class="right">0.0</td>
</tr>
<tr class="TTdata">
<td>13.</td>
<td class="right">2015</td>
<td>Kevin Plawecki</td>
<td class="right">1826</td>
<td class="right">744.0</td>
<td class="right">770</td>
<td class="right">26.0</td>
<td class="right">3.9</td>
<td class="right">3.9</td>
<td class="right">886</td>
<td class="right">9.0</td>
<td class="right">0.0</td>
<td class="right">9</td>
<td class="right">0.0</td>
</tr>
<tr class="TTdata_ltgrey">
<td>14.</td>
<td class="right">2015</td>
<td>David Ross</td>
<td class="right">941</td>
<td class="right">339.6</td>
<td class="right">361</td>
<td class="right">21.4</td>
<td class="right">3.2</td>
<td class="right">3.2</td>
<td class="right">519</td>
<td class="right">5.0</td>
<td class="right">0.0</td>
<td class="right">5</td>
<td class="right">0.0</td>
</tr>
<tr class="TTdata">
<td>15.</td>
<td class="right">2015</td>
<td>Roberto Perez</td>
<td class="right">1969</td>
<td class="right">776.5</td>
<td class="right">789</td>
<td class="right">12.5</td>
<td class="right">1.9</td>
<td class="right">1.9</td>
<td class="right">1090</td>
<td class="right">12.0</td>
<td class="right">0.0</td>
<td class="right">12</td>
<td class="right">0.0</td>
</tr>
<tr class="TTdata_ltgrey">
<td>16.</td>
<td class="right">2015</td>
<td>Welington Castillo</td>
<td class="right">1047</td>
<td class="right">410.6</td>
<td class="right">420</td>
<td class="right">9.4</td>
<td class="right">1.4</td>
<td class="right">1.4</td>
<td class="right">499</td>
<td class="right">4.0</td>
<td class="right">0.0</td>
<td class="right">4</td>
<td class="right">0.0</td>
</tr>
<tr class="TTdata">
<td>17.</td>
<td class="right">2015</td>
<td>Hank Conger</td>
<td class="right">1000</td>
<td class="right">405.2</td>
<td class="right">414</td>
<td class="right">8.8</td>
<td class="right">1.3</td>
<td class="right">1.3</td>
<td class="right">511</td>
<td class="right">4.0</td>
<td class="right">0.0</td>
<td class="right">4</td>
<td class="right">0.0</td>
</tr>
<tr class="TTdata_ltgrey">
<td>18.</td>
<td class="right">2015</td>
<td>Josh Thole</td>
<td class="right">476</td>
<td class="right">168.8</td>
<td class="right">177</td>
<td class="right">8.2</td>
<td class="right">1.2</td>
<td class="right">1.2</td>
<td class="right">275</td>
<td class="right">4.0</td>
<td class="right">0.0</td>
<td class="right">4</td>
<td class="right">0.0</td>
</tr>
<tr class="TTdata">
<td>19.</td>
<td class="right">2015</td>
<td>Tucker Barnhart</td>
<td class="right">934</td>
<td class="right">351.4</td>
<td class="right">357</td>
<td class="right">5.6</td>
<td class="right">0.8</td>
<td class="right">0.8</td>
<td class="right">410</td>
<td class="right">4.0</td>
<td class="right">0.0</td>
<td class="right">4</td>
<td class="right">0.0</td>
</tr>
</tbody>
</table>
In this case, I'm interested in retrieving every "player" that is in a table row with either the class of TTdata or TTdata_ltgrey. This can be achieved using the following:
html = open(url)
doc = Nokogiri::HTML(html)
doc.css('.TTdata, .TTdata_lgrey').each do |catcher|
# parse here
end
My problem is, none of the td entries have classes associated with them. I just know that TD 1 is a position, TD 2 is a year, TD 3 is a name.
What's the right way to access each td using the iteration above so I can create a model/hash of name/val pairs for each row?

Here is one approach I tried. But yes, you can take it further from here to meet the need you have :
require 'nokogiri'
require 'pp'
doc = Nokogiri::HTML.parse(File.read("#{__dir__}/out1.html"))
data = doc.css('.TTdata, .TTdata_lgrey').map do |tr|
%i(position year name).zip(tr.css("td:nth-child(-n+3)").map(&:text)).to_h
end
pp data
output
[{:position=>"1.", :year=>"2015", :name=>"Yasmani Grandal"},
{:position=>"3.", :year=>"2015", :name=>"Francisco Cervelli"},
{:position=>"5.", :year=>"2015", :name=>"Caleb Joseph"},
{:position=>"7.", :year=>"2015", :name=>"Jason Castro"},
{:position=>"9.", :year=>"2015", :name=>"Martin Maldonado"},
{:position=>"11.", :year=>"2015", :name=>"Rene Rivera"},
{:position=>"13.", :year=>"2015", :name=>"Kevin Plawecki"},
{:position=>"15.", :year=>"2015", :name=>"Roberto Perez"},
{:position=>"17.", :year=>"2015", :name=>"Hank Conger"},
{:position=>"19.", :year=>"2015", :name=>"Tucker Barnhart"}]

Related

How set The table cell should be the same width for the whole table except for the first column cells

Highlighted cells should be same width
<table class="tg">
<thead>
<tr>
<th class="tg-baqh" colspan="5">Graduate People</th>
<th class="tg-baqh" colspan="4">Uneducated People</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tg-0lax">City</td>
<td class="tg-baqh">Male</td>
<td class="tg-baqh">Female</td>
<td class="tg-baqh">Trangender</td>
<td class="tg-baqh">Total</td>
<td class="tg-baqh">Male</td>
<td class="tg-baqh">Female</td>
<td class="tg-baqh">Trangender</td>
<td class="tg-baqh">Total</td>
</tr>
<tr>
<td class="tg-0lax">Delhi</td>
<td class="tg-baqh">3000</td>
<td class="tg-baqh">3000</td>
<td class="tg-baqh">200</td>
<td class="tg-baqh">6200</td>
<td class="tg-baqh">1000</td>
<td class="tg-baqh">1000</td>
<td class="tg-baqh">100</td>
<td class="tg-baqh">2200</td>
</tr>
<tr>
<td class="tg-0lax">Mumbai</td>
<td class="tg-baqh">4000</td>
<td class="tg-baqh">4000</td>
<td class="tg-baqh">500</td>
<td class="tg-baqh">8500</td>
<td class="tg-baqh">1400</td>
<td class="tg-baqh">600</td>
<td class="tg-baqh">50</td>
<td class="tg-baqh">2050</td>
</tr>
</tbody>
</table>
I used "table-layout: fixed;" but not get the expected output. Cell content should be the same width as per the transgender data cell.

HTML Table Design issue with 22 column in row with Menu collapse

I have one table shown on screen with menu layout.
While menu is not collapsed the table is showing perfectly on screen like the below image.
But once I Collapse the Menu toggle button the table design is getting out of screen like below image. Last 3 columns were out of screen body.
Below is the code for table I am using.
<table width="100%" border="1" cellpadding="1" cellspacing="2" bordercolor="#999999">
<tbody>
<tr>
<td height="24" width="20%">Customer</td>
<td width="15%">Purchase</td>
<td width="15%">Branch</td>
<td width="15%">Status</td>
<td width="15%">PO Issue date</td>
<td width="15%">Delivery Date</td>
<td width="15%">Return Date</td>
<td width="15%">Approved By</td>
<td width="15%">Equipment Recovery</td>
<td width="15%">Labor Recovery</td>
<td width="15%">Shipping Recovery</td>
<td width="15%">Purchase Recovery</td>
<td width="15%">Other Recovery</td>
<td bgcolor="#E6E6E6"><strong>Total</strong></td>
<td>Equipment Rental</td>
<td>Labor</td>
<td>Shipping</td>
<td>Equipment Purchase</td>
<td>Other</td>
<td>Tax</td>
<td>Loss Code</td>
<td nowrap="nowrap" width="100%">Internal Notes</td>
</tr>
<tr>
<td height="24" colspan="13">
<div align="right"><strong>TOTALS</strong></div>
</td>
<td bgcolor="#E6E6E6">$0.00</td>
<td>$0.00</td>
<td>$0.00</td>
<td>$0.00</td>
<td>$0.00</td>
<td>$0.00</td>
<td>$0.00</td>
<td colspan="2"></td>
</tr>
</tbody>
</table>
Can anybody have look and let me know how I can overcome it.

How to fetch whole row from HTML data through shell script?

I need to fetch whole row from table for that I have taken the table data into HTML format(Please see below data). Now I need to get data for a specific row Ex is suppose I want data for 19.8.2 then whole ROW should be fetched from 8/19/19(Branch cut) to 8/23/19(Prod Deploy)--
<div class="table-wrap">
<table class="wrapped confluenceTable">
<colgroup>
<col style="width: 123.0px;" />
<col style="width: 80.0px;" />
<col style="width: 138.0px;" />
<col style="width: 138.0px;" />
<col style="width: 139.0px;" />
<col style="width: 126.0px;" />
<col style="width: 788.0px;" />
</colgroup>
<tbody>
<tr>
<td class="highlight-green confluenceTd" data-highlight-colour="green">Milestone</td>
<td class="highlight-green confluenceTd" data-highlight-colour="green">Branch Cut</td>
<td class="highlight-green confluenceTd" data-highlight-colour="green">FIT Cert</td>
<td class="highlight-green confluenceTd" data-highlight-colour="green">IAT Cert</td>
<td class="highlight-green confluenceTd" data-highlight-colour="green">UAT Deploy</td>
<td class="highlight-green confluenceTd" data-highlight-colour="green">Prod Deploy</td>
<td class="highlight-green confluenceTd" colspan="1" data-highlight-colour="green">Key Features</td>
</tr>
<tr>
<td colspan="1" class="confluenceTd">19.7.1</td>
<td colspan="1" class="confluenceTd">7/8/19</td>
<td colspan="1" class="confluenceTd">7/9/19</td>
<td colspan="1" class="confluenceTd">7/10/19</td>
<td colspan="1" class="confluenceTd">7/11/19</td>
<td colspan="1" class="confluenceTd">7/12/19</td>
<td colspan="1" class="confluenceTd">
<p><span style="color: rgb(51,153,102);">MOVE TO 3 WEEK RELEASE CYCLE ON FRIDAYS</span></p>
</td>
</tr>
<tr>
<td colspan="1" class="confluenceTd">19.8.1</td>
<td colspan="1" class="confluenceTd">7/29/19</td>
<td colspan="1" class="confluenceTd">7/30/19</td>
<td colspan="1" class="confluenceTd">7/31/19</td>
<td colspan="1" class="confluenceTd">8/1/19</td>
<td colspan="1" class="confluenceTd">8/2/19</td>
<td colspan="1" class="confluenceTd">
<br/>
</td>
</tr>
<tr>
<td colspan="1" class="confluenceTd">19.8.2</td>
<td colspan="1" class="confluenceTd">8/19/19</td>
<td colspan="1" class="confluenceTd">8/20/19</td>
<td colspan="1" class="confluenceTd">8/21/19</td>
<td colspan="1" class="confluenceTd">8/22/19</td>
<td colspan="1" class="confluenceTd">8/23/19</td>
<td colspan="1" class="confluenceTd">
<br/>
</td>
</tr>
<tr>
<td colspan="1" class="confluenceTd">19.9.1</td>
<td colspan="1" class="confluenceTd">9/9/19</td>
<td colspan="1" class="confluenceTd">9/10/19</td>
<td colspan="1" class="confluenceTd">9/11/19</td>
<td colspan="1" class="confluenceTd">9/12/19</td>
<td colspan="1" class="confluenceTd">9/13/19</td>
<td colspan="1" class="confluenceTd">
<br/>
</td>
</tr>
<tr>
<td class="confluenceTd">19.10.1</td>
<td class="confluenceTd">9/30/19</td>
<td class="confluenceTd">10/1/19</td>
<td class="confluenceTd">10/2/19</td>
<td class="confluenceTd">10/3/19</td>
<td class="confluenceTd">10/4/19</td>
<td class="confluenceTd"><span>Q1 - Feature Release</span></td>
</tr>
<tr>
<td class="confluenceTd">19.10.2</td>
<td class="confluenceTd">
<br/>
</td>
<td class="confluenceTd">
<br/>
</td>
<td class="confluenceTd">
<br/>
</td>
<td class="confluenceTd">
<br/>
</td>
<td class="confluenceTd">
<br/>
</td>
<td class="confluenceTd">
<p>This deployment was canceled due to a dev group directed deployment freeze.</p>
<p>Original Dates: Branch: 10/21; FIT: 10/22; IAT: 10/23; UAT: 10/24; Prod: 10/25</p>
</td>
</tr>
<tr>
<td class="confluenceTd">19.11.1</td>
<td class="confluenceTd">11/11/19</td>
<td class="confluenceTd">11/12/19</td>
<td class="confluenceTd">11/13/19</td>
<td class="confluenceTd">11/14/19</td>
<td class="confluenceTd">11/15/19</td>
<td class="confluenceTd">
<br/>
</td>
</tr>
<tr>
<td class="confluenceTd">19.12.1</td>
<td class="confluenceTd">12/2/19</td>
<td class="confluenceTd">12/3/19</td>
<td class="confluenceTd">12/4/19</td>
<td class="confluenceTd">12/5/19</td>
<td class="confluenceTd">12/6/19</td>
<td class="confluenceTd">
<br/>
</td>
</tr>
<tr>
<td colspan="1" class="confluenceTd">20.01.1</td>
<td colspan="1" class="confluenceTd">1/20/20</td>
<td colspan="1" class="confluenceTd">1/21/20</td>
<td colspan="1" class="confluenceTd">1/22/20</td>
<td colspan="1" class="confluenceTd">1/23/20</td>
<td colspan="1" class="confluenceTd">1/24/20</td>
<td colspan="1" class="confluenceTd">Q2 - Feature Release</td>
</tr>
</tbody>
</table>
</div>
<p>** FIT certification delayed 1 day due to Holiday</p>
I tried with below script but getting output is only branch cut column date-Please help.
#!/bin/bash
curl -user -pass --noproxy '*' 'https://confluence.es.com/display/Release+Calendar' | awk ' /<div id="main-content" class="wiki-content">/ {flag=1;next} / <\\/div>/{flag=0} flag { print }' > page.tmp
xmllint --html -xpath'//table/tbody/tr/td[2]' page.tmp | egrep -o '[0-9]{1,2}/[0-9]{1,2}/[0-9]{2,4}' > branchdates.tmp
You will have to get required td and then parent tr of that td. You can do this with following xpath
To get required td
//table//td[contains(text(), '19.8.2')]
To get parent tr of required td
//table//td[contains(text(), '19.8.2')]/parent::tr

Extract text between HTML tags (<tr> </tr>)

I'm trying to extract the text between all <tr> </tr> tags in a string and print them.
use strict;
use warnings;
my $HTML = '
<tr data_1="15,12,2016" data_2="1">
<td class="cl_1">11111</td>
<td class="cl_2">11111</td>
<td class="cl_3"><strong>11111</strong></td>
<td class="cl_4" colspan="3">11111</td>
</tr>
<tr data_1="16,12,2016" data_2="0">
<td class="cl_1">22222</td>
<td class="cl_2">22222</td>
<td class="cl_3"><strong>22222</strong></td>
<td class="cl_4" colspan="3">22222</td>
</tr>
<tr data_1="15,12,2016" data_2="1">
<td class="cl_1">33333</td>
<td class="cl_2">33333</td>
<td class="cl_3"><strong>33333</strong></td>
<td class="cl_4" colspan="3">33333</td>
</tr>
';
while($HTML =~ /data_2="1">(.*)<\/tr>(\R)/sg) {
print "$1\n\n";
}
The output should be:
<td class="cl_1">11111</td>
<td class="cl_2">11111</td>
<td class="cl_3"><strong>11111</strong></td>
<td class="cl_4" colspan="3">11111</td>
<td class="cl_1">33333</td>
<td class="cl_2">33333</td>
<td class="cl_3"><strong>33333</strong></td>
<td class="cl_4" colspan="3">33333</td>
How do I do that and extract the content from each <tr> tag?
Editing answer to include new restriction on which <tr>'s are wanted
my $HTML = '
<tr data_1="15,12,2016" data_2="1">
<td class="cl_1">11111</td>
<td class="cl_2">11111</td>
<td class="cl_3"><strong>11111</strong></td>
<td class="cl_4" colspan="3">11111</td>
</tr>
<tr data_1="16,12,2016" data_2="0">
<td class="cl_1">22222</td>
<td class="cl_2">22222</td>
<td class="cl_3"><strong>22222</strong></td>
<td class="cl_4" colspan="3">22222</td>
</tr>
<tr data_1="15,12,2016" data_2="1">
<td class="cl_1">33333</td>
<td class="cl_2">33333</td>
<td class="cl_3"><strong>33333</strong></td>
<td class="cl_4" colspan="3">33333</td>
</tr>
';
while($HTML =~ /<tr[^>]*data_2=\"1\"[^>]*>(.*?)<\/tr>/msg) {
print "$1\n\n"; }
Output:
<td class="cl_1">11111</td>
<td class="cl_2">11111</td>
<td class="cl_3"><strong>11111</strong></td>
<td class="cl_4" colspan="3">11111</td>
<td class="cl_1">33333</td>
<td class="cl_2">33333</td>
<td class="cl_3"><strong>33333</strong></td>
<td class="cl_4" colspan="3">33333</td>

HTML: Unexpected double row using rowspan

I want to create a normal table. But I need to put two fields in one row.
So, I used rowspan and expected to have a two row table, but with a space of fourth.
But, it's showed in only one line.
I revised, and look for something wrong, but I dont unerstaing.
When I remove the rowspan, everything looks normal, but I need the rowspan.
Why is render in one row?
<table class="table table-bordered">
<tbody>
<tr class="warning" >
<td rowspan="2" >100</td>
<td rowspan="2">87</td>
<td rowspan="2">FERNANDO RODRIGUEZ</td>
<td rowspan="2"></td>
<td rowspan="2">MARIANO ORTEGA SANCHEZ</td>
<td rowspan="2" > </td>
<td rowspan="2" > </td>
<td rowspan="2">
<span class="label label-info">
Importacion
Sencillo
</span>
</td>
<td rowspan="2"> Monterrey </td>
<td rowspan="2" ></td>
<td rowspan="2" ></td>
<td rowspan="2" ></td>
<td rowspan="2">
<a href="/TimsaLzc/web/app_dev.php/main/fleteDetalle/100" >
<button class="btn btn-success">Detalles</button>
</a>
</td>
</tr>
<tr class="warning" >
<td rowspan="2" >101</td>
<td rowspan="2">82</td>
<td rowspan="2">IVAN CORTES</td>
<td rowspan="2"></td>
<td rowspan="2">MARIANO ORTEGA SANCHEZ</td>
<td rowspan="2" > </td>
<td rowspan="2" > </td>
<td rowspan="2">
<span class="label label-info">
Importacion
Sencillo
</span>
</td>
<td rowspan="2"> Nissan Mexico </td>
<td rowspan="2" ></td>
<td rowspan="2" ></td>
<td rowspan="2" ></td>
<td rowspan="2">
<a href="/TimsaLzc/web/app_dev.php/main/fleteDetalle/101" >
<button class="btn btn-success">Detalles</button>
</a>
</td>
</tr>
</tbody>
</table>
This is a picture of my app in action, and the reason of my question.
https://www.dropbox.com/s/1luaxgg4yesm8re/result.png
Replace the rowspans with colspans. For example:
<td colspan="2">
(...)
</td>
EDIT:
Still not 100% sure what you're trying to achieve but as far as I believe you might want to:
remove rowspan from all the td's that are meant to be two-rowed.
add and additional <tr></tr> after each tr and fill it with a number of tds equal to number of cells with rowspan.
I just had a similar problem, try adding an empty Row at the end of the missbehaving Row something like this:
<table class="table table-bordered">
<tbody>
<tr class="warning" >
<td rowspan="2" >100</td>
<td rowspan="2">87</td>
<td rowspan="2">FERNANDO RODRIGUEZ</td>
<td rowspan="2"></td>
<td rowspan="2">MARIANO ORTEGA SANCHEZ</td>
<td rowspan="2" > </td>
<td rowspan="2" > </td>
<td rowspan="2">
<span class="label label-info">
Importacion
Sencillo
</span>
</td>
<td rowspan="2"> Monterrey </td>
<td rowspan="2" ></td>
<td rowspan="2" ></td>
<td rowspan="2" ></td>
<td rowspan="2">
<a href="/TimsaLzc/web/app_dev.php/main/fleteDetalle/100" >
<button class="btn btn-success">Detalles</button>
</a>
</td>
</tr>
<tr /> <!--magic goes here-->
<tr class="warning" >
<td rowspan="2" >101</td>
<td rowspan="2">82</td>
<td rowspan="2">IVAN CORTES</td>
<td rowspan="2"></td>
<td rowspan="2">MARIANO ORTEGA SANCHEZ</td>
<td rowspan="2" > </td>
<td rowspan="2" > </td>
<td rowspan="2">
<span class="label label-info">
Importacion
Sencillo
</span>
</td>
<td rowspan="2"> Nissan Mexico </td>
<td rowspan="2" ></td>
<td rowspan="2" ></td>
<td rowspan="2" ></td>
<td rowspan="2">
<a href="/TimsaLzc/web/app_dev.php/main/fleteDetalle/101" >
<button class="btn btn-success">Detalles</button>
</a>
</td>
</tr>
<tr /> <!--magic goes here-->
</tbody>
</table>
It worked for me :)