| TOP | XML & CGI | 目次 |
| XMLでデータベース |
| XMLデータのクリーニング | |||
| CGIプログラムには配列@dataに以下のように収納されます。 配列0番はXML宣言文があるところなので表示に用いない。(0番にはXML宣言が入ってます) 配列1番にはルート要素+子要素(この場合<新聞雑誌記事>+<記事>)があります。他の配列にそろえるためにルート要素<新聞雑誌記事>は除きます。 配列1番以下データトップに子要素(この場合<記事>)が来ますのでこれを除きます。但し、要素の属性もそれぞれの配列に納める必要があります。 実際に、下のようなデータを配列に入れてみます。 |
|||
![]() |
|||
| 用いたプログラムは次のようなものです。青字部分はタグがあると画面に表示されないのでタグをエスケープしました(これは後で取り去りました)。 各レコードの行末の改行コードを除去します。test01.cgi |
|||
| #!/usr/bin/perl #HTML文を出力するための宣言 print "Content-type: text/html\n\n"; open (IN,"dtb.xml"); @data=<IN>; close(IN); $n=0; foreach(@data){ $data[$n] =~ s/</<\;/g; #htmlタグを禁止する $data[$n] =~ s/>/>\;/g; #htmlタグを禁止する $data[$n] =~ s/\n//g; #改行コードを除く print "\$data\[$n\]\="."$data[$n]<BR>\n"; $n++; print "<P>\n"; } exit; |
|||
![]() |
|||
| ルート要素<新聞雑誌記事>を取り除きます。test02b.cgi | |||
| #!/usr/bin/perl #HTML文を出力するための宣言 print "Content-type: text/html\n\n"; open (IN,"dtb.xml"); @data=<IN>; close(IN); $n=0; foreach(@data){ $data[$n] =~ s/\<$element_root\>//g; #ルート要素始めを除く $data[$n] =~ s/\<\/$element_root\>//g; #ルート要素終わりを除く $data[$n] =~ s/</<\;/g; #htmlタグを禁止する $data[$n] =~ s/>/>\;/g; #htmlタグを禁止する $data[$n] =~ s/\n//g; #改行コードを除く print "\$data\[$n\]\="."$data[$n]<BR>\n"; $n++; print "<P>\n"; } exit; |
|||
![]() |
|||
| 次に<記事>要素の属性の名前と値を取り出す。各々の属性の間にはスペースがひとつあるのでこれで切り分けます。しかし、属性の値の中にもスペースがある可能性があるので
"+スペースで区切ります。 あとあと使いやすくするためにサブルーチンにしました。test02c.cgi |
|||
| #!/usr/bin/perl #HTML文を出力するための宣言 print "Content-type: text/html\n\n"; #データを配列に入れる &data; $n = 1; foreach(@data){ print "\$data\[$n\]\="."$data[$n]<BR>\n"; #属性要素を配列に入れる &zokusei; $m = 0; foreach(@zokusei){ print " "."\$zokusei\[$m\]\="."$zokusei[$m]<BR>\n"; $m++; } print "<P>\n"; $n++; } exit; #==========サブルーチン========== #データを配列に入れる sub data{ open (IN,"dtb.xml"); @data=<IN>; close(IN); $n=0; foreach(@data){ $data[$n] =~ s/\<新聞雑誌記事\>//g; #ルート要素を除く $data[$n] =~ s/</<\;/g; #htmlタグを禁止する $data[$n] =~ s/>/>\;/g; #htmlタグを禁止する chop($data[$n]); #行末の改行コードを除く $n++; } } #要素属性を配列に入れる sub zokusei{ @zokusei=split(/" /,$data[$n]); } |
|||
![]() |
|||
| タイトル左端の<記事を取り除く。(赤字)テキスト端末の</記事>を取り除く。(赤字) コメントにぶら下がっているテキスト(本文)を取り出す。$zokusei[11]の中で、テキストの前には必ず "> があるのでこれを目印にすればいい。(青字) コメントからテキストを除く。(青字ボールド) あとは属性の値の左端の”を取り除く。(黒字ボールド) test03b.cgi |
|||
| #!/usr/bin/perl #HTML文を出力するための宣言 print "Content-type: text/html\n\n"; #データを配列に入れる &data; $n = 1; foreach(@data){ print "\$data\[$n\]\="."$data[$n]<BR>\n"; &zokusei; $m = 0; foreach(@zokusei){ print " "."\$zokusei\[$m\]\="."$zokusei[$m]<BR>\n"; $m++; } print " "."\$text\[$n\]\="."$text[$n]<BR>\n"; print "<P>\n"; $n++; } exit; #==========サブルーチン========== #データを配列に入れる sub data{ open (IN,"dtb.xml"); @data=<IN>; close(IN); $n=0; foreach(@data){ $data[$n] =~ s/\<新聞雑誌記事\>//g; #ルート要素を除く $data[$n] =~ s/</<\;/g; #htmlタグを禁止する $data[$n] =~ s/>/>\;/g; #htmlタグを禁止する chop($data[$n]); #行末の改行コードを除く $n++; } } #要素属性を配列に入れる/テキストの抽出 sub zokusei{ @zokusei = split(/" /,$data[$n]); #属性を各配列に納める $zokusei[0] =~ s/<\;記事 //; #タイトルから<記事 を取り除く $zokusei[11] =~ s/<\;\/記事>\;//g; #コメントから</記事>を取り除く $l = index($zokusei[11],"\">\;"); $text[$n] = substr($zokusei[11],$l+5); #テキストを取り出す $zokusei[11] = substr($zokusei[11],0,$l $m = 0; foreach(@zokusei){ $zokusei[$m] =~ s/"//g; #最後に残った " を取り除く $m++; } } |
|||
| コメントの末尾の文字が化けてしまう問題が生じる。 | |||
![]() |
|||
データの区切れが図のように違っていた。左の場合はコメント・データが一部削られてしまったようだ。 $zokusei[11] = substr($zokusei[11],0,$l-1); 最後の-1が間違っていたようでした。(これは要らない)文字列を取り出す時の考え方の誤解でした。(index($○○○,□□)の返す値は文字を数えるのではなく、文字と文字の間を数えるのでした) |
|||
![]() |
|||
| @zokuseiには配列0〜11番まで「属性名」と「値」が入っています。「属性名」は必要ないので「値」だけにします。「属性名」と「値」の間には = があり、これで区切ることができます。test03c.cgi | |||
| #!/usr/bin/perl #HTML文を出力するための宣言 print "Content-type: text/html\n\n"; #データを配列に入れる &data; $n = 1; foreach(@data){ print "\$data\[$n\]\="."$data[$n]<BR>\n"; &zokusei; $m = 0; foreach(@zokusei){ print " "."\$zokusei\[$m\]\="."$zokusei[$m]<BR>\n"; $m++; } print " "."\$text\[$n\]\="."$text[$n]<BR>\n"; print "<P>\n"; $n++; } exit; #==========サブルーチン========== #データを配列に入れる sub data{ open (IN,"dtb.xml"); @data=<IN>; close(IN); $n=0; foreach(@data){ $data[$n] =~ s/\<新聞雑誌記事\>//g; #ルート要素を除く $data[$n] =~ s/</<\;/g; #htmlタグを禁止する $data[$n] =~ s/>/>\;/g; #htmlタグを禁止する chop($data[$n]); #行末の改行コードを除く $n++; } } #要素属性を配列に入れる/テキストの抽出 sub zokusei{ @zokusei = split(/" /,$data[$n]); #属性を各配列に納める $zokusei[0] =~ s/<\;記事 //; #タイトルから<記事 を取り除く $zokusei[11] =~ s/<\;\/記事>\;//g; #コメントから</記事>を取り除く $l = index($zokusei[11],"\">\;"); $text[$n] = substr($zokusei[11],$l+5); #テキストを取り出す $zokusei[11] = substr($zokusei[11],0,$l-1); #属性の値を取り出す $m = 0; foreach(@zokusei){ $zokusei[$m] =~ s/"//g; #最後に残った " を取り除く $l=index($zokusei[$m],"\="); #属性名を除く $zokusei[$m]=substr($zokusei[$m],$l+1,length($zokusei[$m])-$l); $m++; } } |
|||
![]() |
|||
| 上の図で書式が崩れているところを見つけました。データを見ると$zokusei[11]の値と区切りの"(クォーテーション)がくっついていました。他のデータはスペースがあります。これはどういう事だろう??どうもそれはスペースではなく、上の文字化けに見られるように<BR>のエスケープコードの一部が残ってしまったものだろうか。(下は直ったもの) | |||
![]() |
|||