入力から素材を取り出すとはどういうことか
今回は、「入力から素材を取り出す」ことを話題にします。「入力から素材を取り出す」ことは、次のように言い換えることができます。
- 与えられた具体的なデータに対して、そこに内在する抽象的構造を見抜き、その構造を、より扱いやすい形にして抽出する。
このことを少し掘り下げてみます。
内容:
- 同期のための構造変換と素材
- 情報内容、情報構造
- 情報の抽出は簡単か
- 困難をどう解決するか
同期のための構造変換と素材
まずは、坂田さんの記事「コンテンツ同期は構造変換同期で」の復習と引用をします。
上記の記事で、PC向けWebページとスマートフォン向けのWebページを同期する方法として、「サブツリー同期」と「構造変換同期」という2つの方法が紹介されています。一番目の方法である「サブツリー同期」とは、PC向けドキュメントツリーの、とあるノードから下のサブツリーをそのままスマートフォン向けドキュメントとする方法です。サブツリーを取るので、もとのドキュメントツリーよりはサイズが小さくなりますが、サブツリー内部の複雑さは変わりまん。
「サブツリー同期」は簡便ですが、問題を含むことは明らかです。そこで二番目の方法として「構造変換同期」が登場します。坂田さん記事から引用しましょう:
もう1つは、構造変換同期であり、素材データだけを抽出して新たにスマホ用のツリーを構築するものです。
サブツリー同期の問題に対応したのが、構造変換同期で、入力ツリーのデータ構造を解析して素材データを抽出し、PCサイトの構造は捨ててしまいます。
取り出した素材データは予め設計されたスマホ用のデータ構造に変換して出力します。
「素材データ」という言葉が繰り返し使われていますが、これは「PC向けWebサイト/Webページは、スマートフォン向けWebサイト/Webページを構築するための素材置き場である」という考え方を反映したものです。
多くの人は、PC向けWebページに実現された見た目や挙動もそっくりスマートフォン向けページに“同期する”ことを希望するでしょう。しかし残念ながら、それは技術より魔法の範疇に入ります。タギングやCSSで作り込んだレイアウト、JavaScriptで頑張ったUIを、スマートフォンでも使えれば素晴らしいことですし、そのための努力はされるべきです。とはいえ、今、現実的なアプローチは、見た目や挙動を捨てても、情報内容(informational content)は絶対に同期することです。この情報内容の実質であるデータを「素材」と言っているのです。
情報内容、情報構造
簡単な例を示しましょう。入力がHTMLの箇条書きであるとして、そこから情報の本質を抜き出します。次が箇条書きの例です。
<ol> <li>バナナ</li> <li>リンゴ</li> <li>オレンジ</li> </ol>
「情報内容」と「情報構造」に明確な境界はないのですが、ここでは、コンテンツに含まれるテキストや画像を情報内容、それがどのように編成されているか? 組み立て方を情報構造と言うことにします。
さて、上記の箇条書きの情報内容は、3つの文字列(テキスト) “バナナ”、”リンゴ”、”オレンジ” と考えられます。この3つがこの順序に並んでいることが情報構造を与えます。ol(ordered list)タグは、並びに意味があることを示唆します。
この簡単な例では、HTMLマークアップが情報内容と情報構造をズバリそのまま表現しているのですが、あえてJSON形式で書き換えてみましょう。「3つの文字列が、ある順序で並んでいる」というデータ構造をJSONで書くなら:
- [“バナナ”, “リンゴ”, “オレンジ”]
となります。この箇条書きが「果物を好きな順に並べた」ものとすれば、次のデータ構造は元の情報を保持してません。
- [“リンゴ”, “オレンジ”, “バナナ”]
3つの文字列は同じですが、順序構造を壊してしまっているのです。
もうひとつ例を挙げましょう。
<ol class="wide important"> <li onclick="banana();">バナナ</li> <li>リンゴ</li> <li style="color:orange">オレンジ</li> </ol>
これは、HTML断片としては先の例と異なります。ブラウザによる表示と挙動も違うでしょう。ですが、情報内容(3つの文字列)と情報構造(順序を持つ並び)を抽出すると、やはり次の文字列配列となります。
- [“バナナ”, “リンゴ”,”オレンジ”]
念のため注意しますが、二番目の例に出てくる class、onclick、style などを「捨てるべきだ」とは言ってません。活かせるものなら活かしたいのはやまやまです。情報内容/情報構造の保存と天秤にかけると、見た目/挙動の保存は優先度が下がる、ということなのです。
情報の抽出は簡単か
坂田さん記事「コンテンツ同期は構造変換同期で」より:
構造変換同期では、出力構造が決まっていて、その構造に必要な素材データを入力サブツリーから探し出してきます。探索アルゴリズムは、データ構造やデータパターンを想定して組むため、同じ構造を有してさえいれば、数の違いや不要な要素の出現パターンが違っても、必要なデータを見つけ出します。このことは、PCコンテンツの変更自由度を高く保ちながら、高い精度の同期を実現できます。
これは、ジーンコード(GC)が実際に行なっている処理ですが、それほど簡単というわけではありません。入力が箇条書きだと想定して、そこから「文字列配列」という素材を抽出する例を考えてみましょう。
先に挙げた2つの例なら、DOMプログラミングでもテキスト処理でも、「なんとかなりそうだ」と感じたかも知れません。入力が素直なら、素材(情報内容、情報構造)の抽出は簡単です。しかし、既存のWebページが、素直で整ったマークアップ(したがって、素直で整ったツリー構造)を持つとは限りません。別な例を見てみましょう。
<ol> <li>わたしが<strong>大好きな</strong>バナナ</li> <li><a href="https://ja.wikipedia.org/wiki/%E9%85%B8%E5%91%B3" target="_blank">酸味</a>が魅力なリンゴ</li> <li>マーマレードでもおいしい<span style="color:orange">オレンジ</span></li> </ol>
箇条項目(list item)のなかにインライン要素が出てきてます。単なるテキストじゃありません。想定外の要素は内容ごと捨てる戦略で処理すると:
- [“わたしがバナナ”, “が魅力なリンゴ”, “マーマレードでもおいしい”]
という文字列配列が得られます。これでは、情報が保存されたとはとても言えませんね。要素を囲むタグ(開始タグと終了タグ)だけを落とすと、まーまー、意味が通じる素材が得られます。
- [“わたしが大好きなバナナ”, “酸味が魅力なリンゴ”, “マーマレードでもおいしいオレンジ”]
次はどうでしょうか?
<ol> <p>わたしが大好きな</p> <li>バナナ</li> <p>酸味が魅力な</p> <li>リンゴ</li> <p>マーマレードでもおいしい</p> <li>オレンジ</li> </ol>
箇条書きのなかにいきなり段落を入れるなんて、ひどいマークアップです。ブラウザはそれなりに表示しますが、素材抽出プログラムにとっては難儀なことになります。
さらに、次なら?
<ol> <table> <tr><td>わたしが大好きな</td></tr> <li>バナナ</li> <tr><td>酸味が魅力な</td></tr> <li>リンゴ</li> <tr><td>マーマレードでもおいしい</td></tr> <li>オレンジ</li> </table> </ol>
いやはや、テーブルですか。こうなると、さすがに寛容なプラウザも、そのまま表示することはできず、ドキュメントツリーを次のように変形します(Firefoxで確認)。
<ol> <li>バナナ</li> <li>リンゴ</li> <li>オレンジ</li> <table> <tbody> <tr><td>わたしが大好きな</td></tr> <tr><td>酸味が魅力な</td></tr> <tr><td>マーマレードでもおいしい</td></tr> </tbody> </table> </ol>
とんでもない例を出しましたが、次はマトモなマークアップと言っていいでしょう。
<ol> <li>果物 <ol> <li>バナナ</li> <li>リンゴ</li> <li>オレンジ</li> </ol> </li> <li>野菜 <ol> <li>ニンジン</li> <li>キャベツ</li> <li>キューリ</li> </ol> </li> </ol>
しかし、素材抽出プログラムが入れ子の箇条書きを想定してなかったなら、うまく処理できないことになります。
素材抽出プログラムは、「データ構造やデータパターンを想定して組む」のですが、その想定とは、情報の抽象的な構造です。実際に与えられた具体的な入力が“想定外”のとき、処理は失敗します。より広い範囲の入力を受け付けるようにすると、出力の精度が下がります。狭い入力範囲に特化したほうが精密な結果が得られるのです。どんな入力でもOKで、高い精度の出力を出すこと — これはまた魔法になってしまいます。
筆者(檜山)の個人ブログで、プログラムへの入力の範囲を広げることが大変であることを、お菓子屋さんの例え話で説明したことがあるので、興味がある方は参照してください。(なお、以下の記事の例え話に出てくる「素材」はケーキの素材なので、今回の話題から言うと「入力」のことです。)
困難をどう解決するか
素材抽出プログラムが、「(1) より広い範囲の入力を許容」し、「(2) より精度の高い結果を出力する」ように改善することは可能です。しかしこれは、アルゴリズムやプログラミング・テクニックによる改善であり、魔法を使えない我々には限度があります。
要点は、入力(PC向けWebページのツリー構造)に対して、できるだけ正確な想定をすることです。想定の正確さは、事前の知識に依存します。未知の対象物に関しては想定や予測はできません。入力の「データ構造やデータパターン」に対する知識が豊富なら、正確で失敗しない素材抽出プログラム作ることができます。
坂田さん記事の最後の一文は、この事情を背景にしてます。
高い運用性と同期性を確保するためには、PCコンテンツの運用を理解していることが圧倒的に重要です。
最後にまた注意を述べると: 入力に対する正確な想定が必要なのは「より精度の高い結果」を望むときです。出力(スマートフォン向けWebページ)に対する要求が厳しくないときは、汎用の素材抽出プログラムでもけっこういける、というのも我々の知見のひとつです。