• ベストアンサー

変動する

はじめまして CGIを学んで1ヶ月の者です。 実は、仕事で少し面倒な依頼を受けて困っております。 内容はCSV形式のデータをPerlで読み取ってそれを HTMLのテーブルに流し込むスクリプトなのですが、 慣れていないので思考停止をして進みません。 具体的なCSVデータの例ですが、 10,果物,りんご,ringo.html,ぶどう,budou.html,ばなな,banana.html,10,野菜,かぼちゃ,kabotya.html,なす,nasu.html,きゅうり,kyuri.html,魚,まぐろ,maguro.html,さけ,sake.html,10,肉,牛,usi.html,麺,ラーメン,ra-men.html,そば,soba.html,うどん,udon.html まず、先頭に10があり、これは分類の区切りを示すヘッダーです。 次に果物でこれは、分類名です。 次にりんご、これは分類詳細名です。 つぎにringo.htmlでこれは分類詳細名のリンク先アドレスです。 このようなデータの並びですが、各分類と詳細項目は変動しますので このテーブルのあるWEBページを毎回読み直す必要があります。 どうのようにしたらよいのでしょうか。 お助けください。

質問者が選んだベストアンサー

  • ベストアンサー
  • callhiro
  • ベストアンサー率35% (54/152)
回答No.13

たびたび登場です。 前回紹介したのは基本的な間違いがいっぱいありました。 あと「全角スペース」がよけいにあってはいけないこともわかりました。 この掲示板では、全角スペースを入れないと左詰になってしまい、 みにくなりますが、 コピーした後半角スペースかタブで調節して見やすくしてください。 この前の失敗 1. 「$i」とすべきところを「i」としている箇所が多い 2. 「$title_color」を突然書いていた→「bgcolor=$title_color」 3. よけいな全角スペースがあった→すべての全角スペースを無くしました 以上をふまえて、hoomaさんのスクリプトを集成し、 実際に試してみてちゃんと実行できました。 どうぞお試しあれ。 htmlの表示部分から修正スクリプトを載せておきます。 ------------------------------------------ print "Content-type:text/html\n\n"; print "<html>\n"; print "<body>"; $title_color = "#6699cc"; print "<table>\n"; foreach $output (@lines){ @table= split(',',$output); for($i=0;$i+1<$#table;$i=$i+2){ if($table[$i] == 10){ print"<tr><td bgcolor=$title_color>$table[$i+1]</td></tr>\n"; next; } if($table[$i] == 20 && $table[$i+2] == 30){ print"<tr><td><a href=$table[$i+3]>$table[$i+1]</a></td></tr>\n"; $i = $i+2; next; } if($table[$i] == 20 && $table[$i+2] != 30){ print"<tr><td>$table[$i+1]</td></tr>\n"; next; } } } print"</table>"; print "</body>\n"; print "</html>\n"; ------------------------------------------

hooma
質問者

お礼

ありがとうございました。 お礼がしたいのでメールアドレスを教えてください。

その他の回答 (12)

  • callhiro
  • ベストアンサー率35% (54/152)
回答No.2

1からなんですね。了解です。 ちなみに他のプログラムは経験ありますか? 僕はもともとC言語はやったことあったので、 Perlを身につけるのは、簡単なリファレンスを見れば 最初から知っていたのと同じぐらいの感覚で使えましたけど。 しかし、まったくプログラムが初めてだと難しいかもしれませんね。 1がわからないとすると、もっと前の部分がわからない可能性がありますね。 簡単に先ほど箇条書きしたとこだけ説明しておきますね。 それ以前でもっとわからないならまた補足してください(笑) ただ、僕も自分の書きやすいように書いていますので、 他の方が見たら、「もっときれいに書けるのに」って思われてしまうかもしれませんが、 そのあたりはどうかお許しください。 まずはこんな風にやっていけば良いんだなとわかっていただければいいかと思います。 1. データを読み込む ~~~~~~~~~~~~~~~~~~ if (!open(DB,"$file")) { &error(1); } @lines = <DB>; close(DB); ってのが僕がよくやるファイルの読み込みです。 このまま使って、「@lines」とか「DV」という文字を適当に変更すればいいです。 errorの関数は、ファイルが開けなかった場合だけ呼び出されます。 (これも別のところで作成しなければなりませんけどね) その必要がない場合は open(DB,"$file"); @lines = <DB>; close(DB); でも良いかもしれません。 $fileには読み込みたいファイルにアクセスするパスを書きますが、 たいてい最初に $file = "food.csv"; とか $file = "../data/food.csv"; などと書いておけば大丈夫です。 もちろんファイルを開くところに直接書いても良いですね。 これがうまくいけば、「@lines」にcsvファイルが行単位で取り込まれます。 つまり 10,果物,りんご,ringo.html,ぶどう,budou.html,ばなな,banana.html 10,野菜,かぼちゃ,kabotya.html,なす,nasu.html,きゅうり,kyuri.html,魚,まぐろ,maguro.html,さけ,sake.html 10,肉,牛,usi.html,麺,ラーメン,ra-men.html,そば,soba.html,うどん,udon.html というデータだとすると、 $lines[0] に果物の行がそのままは入り(「,」等も含んだ形で) $lines[1] に野菜の行が入り $lines[2] に肉の行が入ります 元のデータはすべて一行に表されているんですか? そうだとしたら、全データが$lines[0]に入りますので、 後でデータを分割する必要がありますね。 2. 読み込んだデータを変数に代入する ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 次に書く配列に入れたデータを、より使いやすく小さく区切ります。 その際にsplitという関数を使います。 splitは、各行から特定のパターンで文字列を分割します。 今回のcsvファイルならば、「,」でデータが区切られているので、 「,」を切り分けのパターンとして「果物」「りんご」「ringo.html」などのデータを取り出します。 現在は、 $lines[0] = "10,果物,りんご,ringo.html,ぶどう,budou.html,ばなな,banana.html"; という状態でデータが入っていますので 最初の2つだけデータの意味が違うのでそこを切り出して、 さらに2つずつ切り出さないとだめですね(なんだか切り出しにくいかも)。 まず、 ($no,$type,$data) = split(/,/,$lines[0]); としてみたとします。 この場合、 $no = 10; $type = "果物"; $data = "ringo.html,ぶどう,budou.html,ばなな,banana.html"; という風に変数に代入されます。 後は$dataにあるデータがまだ分割しきれていないのでさらに細かく分ければいいかと思います。 3つずつセットのようなので、 for文などをうまく利用すればすっきり分割できるかもしれません。 ・・・あまりに中途半端ですが、 ちょっと寝る時間を大幅に過ぎてしまいましたので(朝6時起きなんですよね;;) 今日は寝ます(笑) 2の補足、3についてはまた書き込ませていただこうかと思いますが、 ご自分で本などをみてわかっていただければ幸いです。 自分でだんだん理解して、それがほんとに実現できるのがうれしいもんですしね。 他の方もどんどん回答してあげてください。 ではではまた~(^^;)/

hooma
質問者

お礼

夜遅くまで、考えていただいてありがとうございます。 まだ、解決しておりませんが、他の方もアドバイスして下さって本当に感謝です。 もうすこし、すっきりとしたらいいのですが、まだつかみきれてない感じです。

  • callhiro
  • ベストアンサー率35% (54/152)
回答No.1

CGIを学んで一ヶ月ということですが、 どのぐらいのことを理解されているのでしょうか? split等の関数の存在とかもご存じない状態ですか? 基本的な流れですと(僕の思う基本ですが) 1. データを読み込む 2. 読み込んだデータを変数に代入する(ここでsplit等を使います) 3. 変数の個数情報なども利用しながら、foreachなどの繰り返し処理で表を作る といったものになると思います。 どのへんでつまづいておられますか? CGIの本や、WEBにもたくさんリファレンスがありますし、 1ヶ月もあればこのぐらいのプログラムならできると思いますよ。 補足していただければまた現れます。 他の方が答えてしまえばそのままお任せしますが。

hooma
質問者

補足

ご回答ありがとうございます。 わたくしのperlレベルですが、 かなり低いです。 今月の初めにperl入門書を買って、 チマチマとやっている程度です。 仕事はグラフィックデザインの担当ですが、 簡単なCGIくらい組めないとと思い学習しております。 現在、つまづいているのは、ご回答の手順の1番からです。 いろいろなperlのリファレンス本も買いあさりましたが、 基礎がないもので使いこなせない状態です。 なぜsplitを使わないといけないのか、またforeachを実際どのようにして今回のスクリプトへ取り入れるのかがピンときません。 その他に、読み込んだ配列を元に表をつくるには if文とfor文で作りあげるのでしょうけど、 思考停止の状態でかんがえられないので困っています。

関連するQ&A