HTML(と思われているもの)をなめるな

半分ネタだが、仕様の読みかたの練習に。と思ったけど、金をもらって書いている記事にしちゃひどすぎる気もしてきた。DISりたい。

ちなみに題名は「月をなめるな」のパクリです。

まずお題は以下のとおり:

図1に示すHTML形式のテキスト・データ(以下,HTMLデータ)があります。このHTMLデータをブラウザに表示させたときに「表示される文字列」と「その文字列に対して有効なタグ名」を対応付けるアルゴリズムを考えてください。結果は配列に格納して,画面に表示させるものとします(図2)。

第6回 上手なアルゴリズムの見つけ方 | 日経 xTECH(クロステック)

一目見て

表示される文字列って??

noscript や noframe のなかの文字は表示されるんだろうか? titie のなかはブラウザ画面中には現れないよな。これはそれに入る? w3mだったら img の alt属性とかも見たほうがいいかも。

有効なタグ名?!

HTMLは一般に閉じタグはいらない。SGMLのルールで、自動的にタグを閉じてくれるからだ。たとえば <li>の次に <li> があれば、liが入れ子になることはなく自動的に閉じタグ (</li>) があるとみなされる。

で、どのタグがどのタグで閉じられるかというのは、HTMLに関するヒューリスティック、すなわち DTDを知っていなくてはいけない。そこそこハードだ。

そういう面倒くさいところを省くために XMLでは well-formed って概念を導入したんだよな。つまり、必ずタグは明示的に閉じなきゃいかんってこと。ありがたい。

エスケープ処理が面倒なんだよな

">"があったらすぐにタグの終わりだと思うわけにはいかない。属性値のなか、quoteに囲まれてあるかもしれないからだ。ここで状態遷移機械を作らなきゃいけない。

いやらしい例では script要素のなかにあることもある。以前は script要素のなかはコメントアウトするのがマナーだったけど、最近はどうなんだろ。皆外部スクリプトにしているのかな。

世の腐ったHTMLはどうしよう...

さて、以上はすべて HTMLの仕様から導かれる話しではあるが、もしも世の Webページに適用しようとすると、上だけでは不十分だ。

それは、Web上にある HTMLのほとんどは腐っているからだ。DTDを守ってないのが普通だ。入れ子じゃなくてねじれ (<b>..<i>..</b>...</i> みたいな)の関係になってたりする。どうやって救えばいいんだろう...エラーではじいちゃっていいのかな。

encodingは?

日本語の encodingはどうなっているんだろう?? EUCUTF-8だったら楽だ。
でももしも ISO2022JPだったら、現在どの文字セットが指示されてるかの状態を持たなきゃいけないんじゃ? ShiftJISでも2バイト目とかの状態が..
でも < とかの文字は JIS-X0208では使わないんだったっけ。忘れちゃったよ。調べなきゃいけないじゃん。

いろいろ

実際に世の HTMLをパースするコードを書いた事がある人なら、これだけのことを考えるはずだ。
で、そういうことがややこしいからこそ、先人が作ってくれたライブラリをかを使うことにする。それが普通のやり方ってもんだ。

で、正解は?

で、記事を読んで正解を見たら..ええ、そんな単純なのでありかよ。脱力しました。確かにこれで「図1」の例は処理できるよ。でもそれだったら以下のコードで十分じゃん:

#include <stdio.h>

int
main(int argc, char **argv)
{
   puts("html::head::title\tHTMLの読み込みアルゴリズムで解決する\n"
        "html::body::h1\t問題\n"
        "html::body::b\t図1\n"

打ち込むのが面倒くさくなったのでこれでおしまい :-)。

まあ、仕様を読むだけじゃなくて、もっと深い意図を探らなきゃいけないっていう教訓にしておきます。

最後っ屁

にしてもこの回答のソースコードはひどいな。

  • カプセル化が全くなされておらず、extern変数さわりまくり。
  • 8とか 3とかのマジックナンバー頻出
  • 意図しているデータ構造がサッパリわからん (スタックになにが詰まれるんだ??)
  • Cなのに "true"とかの C++予約語は使わないで欲しい。エラーになるコンパイラもあるんだよ。

なんか、言語仕様を覚えた高校生が嬉々として書いているようなコードに見えるよ。動くんだからいいじゃんって。仕事でこういうコードを書かれるとケツを拭くのが大変だからやめてくれ。

できれば、この連載を読んだ人はプログラミング作法でも読んで、脳みそを洗いなおして欲しい。

プログラミング作法

プログラミング作法