[ruby-list:46867] Re: html→csv変換|tableのセル結合に対応したものは?

From: Shin-ichiro HARA <sinara@...>
Date: 2010-02-20 14:51:26 UTC
List: ruby-list #46867
原です。

>  吉泉といいます。
>  昨年9月、htmlのtable(セル結合あり)をcsvに変換する方法について質問さ
> せていただきましたが、関連して、今更の自己resです。
> 
>  table部分をrubyの配列に変換するメソッドを書きました。
>      table_str = '<table>   ...</table>'
>      ary = table_to_array(table_str)
> のようにすると、2次元配列 ary を得ます。配列の各要素は、htmlタグを除
> 去したテキストです。
>  テキストでなく、タグ付きの「<td>  ...</td>」を各要素に記録したい時は
>      ary = table_to_array(table_str, :HTML)
> とします。
>  なお、htmlパーサにはhpricotを使っています。

たまたま私も html のテーブルを読まねばならない仕事があったので、興味
を持ちました。この問題を考えて見たのですが結構むずかしいですね。私な
りの答えを書きます。

  def table_to_array2(tbl_str, data_type=:TEXT)
    tbl = Hpricot(tbl_str)
    trs = tbl.search("tr")
    aa = []
    span = {}
    trs.each_with_index{|e, row_n|
      a = []
      col_n = 0
      e.search("td").each{|e2|
        while span[[row_n, col_n]]
          a.push("")
          col_n += 1
        end
        data = data_type == :TEXT ? e2.inner_text : e2.to_html
        a.push(data)

        cspan = 1
        if e2.attributes['colspan'] =~ /(\d+)/
          cspan = $1.to_i
        end
        rspan = 1
        if e2.attributes['rowspan'] =~ /(\d+)/
          rspan = $1.to_i
        end
        for r in row_n...(row_n+rspan)
          for c in col_n...(col_n+cspan)
            span[[r, c]] = true
          end
        end

        col_n += 1
      }
      aa.push(a)
    }
    return aa
  end

span で省かれた要素を "" で表すという仕様は若干問題あるかもしれませんね。
もともとのデータが空である場合と区別がつかないので。

In This Thread