目次
DOM ツリー生成処理
HTML 解析ステート マシン
文法チェック
タグの補完
ケース スタディ
タグがなくなったらどうなりますか?
ホームページ ウェブフロントエンド htmlチュートリアル Jsoupコード解釈その6-パーサー(その2)_html/css_WEB-ITnose

Jsoupコード解釈その6-パーサー(その2)_html/css_WEB-ITnose

Jun 24, 2016 am 11:26 AM

最近生活が少し忙しくて、いつも夜中に起きていて精神状態があまり良くありません。仕事もうまくいきません。アイデアはたくさんありますが、コードほどうまくいかないものもあります。忘れてください、私はまだ正しい姿勢を持っています。結局のところ、私の資格はまだ若いので、私は私の資格を続けます。

Jsoup のソース コードを読むのは退屈ではありません。結局のところ、パーサーもクローラーの重要なコンポーネントの 1 つです。コードを読んだ後、多くのことを得ることができ、HTML の知識も向上しました。

DOM ツリー生成処理

ここで TreeBuilder の部分を分けて構文解析処理と呼ぶのは少し不適切かもしれませんが、実際には Token に基づいて DOM ツリーを生成する処理です。このコンパイラでは。

TreeBuilder もファサード オブジェクトです。実際の構文解析は次のコードです。

protected void runParser() { while (true) { Token token = tokeniser.read();process(token);if (token.type == Token.TokenType.EOF) break; }}
ログイン後にコピー

TreeBuilder には、HtmlTreeBuilder と XmlTreeBuilder という 2 つのサブクラスがあります。 XmlTreeBuilder は当然、XML ツリーを構築するためのクラスです。実装は基本的にスタックを維持し、さまざまなトークンに従ってノードを挿入します。

@Overrideprotected boolean process(Token token) { // start tag, end tag, doctype, comment, character, eof switch (token.type) { case StartTag: insert(token.asStartTag()); break; case EndTag: popStackToClose(token.asEndTag()); break; case Comment: insert(token.asComment()); break; case Character: insert(token.asCharacter()); break; case Doctype: insert(token.asDoctype()); break; case EOF: // could put some normalisation here if desired break; default: Validate.fail("Unexpected token type: " + token.type); } return true;}
ログイン後にコピー

insertNode のコードはおおよそ次のとおりです (表示の都合上、一部のメソッドは次のようになります)。統合):

Element insert(Token.StartTag startTag) { Tag tag = Tag.valueOf(startTag.name()); Element el = new Element(tag, baseUri, startTag.attributes); stack.getLast().appendChild(el); if (startTag.isSelfClosing()) { tokeniser.acknowledgeSelfClosingFlag(); if (!tag.isKnownTag()) // unknown tag, remember this is self closing for output. see above. tag.setSelfClosing(); } else { stack.add(el); } return el;}
ログイン後にコピー

HTML 解析ステート マシン

XmlTreeBuilder と比較して、HtmlTreeBuilder は実装がより複雑です。同様のスタック構造に加えて、HtmlTreeBuilderState は HTML を分析するためのステート マシンの構築にも使用されます。どうしてこれなの? HtmlTreeBuilderState でどのような状態が使用されているかを確認することもできます (コード内で状態を示します)。

<!-- State: Initial --><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><!-- State: BeforeHtml --><html lang='zh-CN' xml:lang='zh-CN' xmlns='http://www.w3.org/1999/xhtml'><!-- State: BeforeHead --><head> <!-- State: InHead --> <script type="text/javascript"> //<!-- State: Text --> function xx(){ } </script> <noscript> <!-- State: InHeadNoscript --> Your browser does not support JavaScript! </noscript></head><!-- State: AfterHead --><body><!-- State: InBody --><textarea> <!-- State: Text --> xxx</textarea><table> <!-- State: InTable --> <!-- State: InTableText --> xxx <tbody> <!-- State: InTableBody --> </tbody> <tr> <!-- State: InRow --> <td> <!-- State: InCell --> </td> </tr> </table></html>
ログイン後にコピー

ここで、HTML タグには 、 などのネスト要件があることがわかります。

を組み合わせて使用​​します。 Jsoup コードによると、HtmlTreeBuilderState が次のことを行うことがわかります:

文法チェック

たとえば、tr が table タグ内でネストされていない場合、構文エラーになります。以下のタグがInBody状態に直接出現するとエラーが発生します。 Jsoup でこの種のエラーが発生した場合は、トークン解析を見つけてエラーを記録し、直接終了せずに次のコンテンツの解析を続けます。

InBody { boolean process(Token t, HtmlTreeBuilder tb) { if (StringUtil.in(name, "caption", "col", "colgroup", "frame", "head", "tbody", "td", "tfoot", "th", "thead", "tr")) { tb.error(this); return false; } }
ログイン後にコピー

タグの補完

たとえば、head タグが閉じられておらず、本文にのみ表示できるタグがいくつか書かれている場合、自動的に が閉じられます。 HtmlTreeBuilderState には、自動タグ補完を提供するメソッド anythingElse() があります。たとえば、InHead 状態の自動終了コードは次のとおりです。

private boolean anythingElse(Token t, TreeBuilder tb) { tb.process(new Token.EndTag("head")); return tb.process(t); }
ログイン後にコピー

次のようなタグ終了メソッドもあります。

private void closeCell(HtmlTreeBuilder tb) { if (tb.inTableScope("td")) tb.process(new Token.EndTag("td")); else tb.process(new Token.EndTag("th")); // only here if th or td in scope}
ログイン後にコピー

ケース スタディ

タグがなくなったらどうなりますか?

さて、パーサーのソース コードをたくさん読んだ後は、日常のアプリケーションに戻ったほうがよいでしょう。ページ上にさらに 1 つまたは 2 つの閉じられていないタグを記述するのが通常であることはわかっていますが、それらはどのように解析されるのでしょうか?

タグを例に挙げます:

  • 開始タグを忘れて終了タグだけを書きました
おめでとうございます、この
はエラーとして扱われるため、ページは間違いなくめちゃくちゃでした!もちろん、単に を追加しただけでは、何の影響もありません。 (タグが閉じられないようにするために、ページの一番下にもう少し を書くという話を誰かがしてくれたのを覚えています)

    開始タグを書きましたが、終了タグを見逃していました
分析しましょうこの状況はもう少し複雑です。内部にコンテンツをネストできないタグの場合、受け入れられないタグが見つかったときに閉じられます。
タグにはほとんどのタグを含めることができ、その場合、その有効範囲は HTML の最後まで続きます。

さて、パーサーシリーズの解析は終わりましたが、この期間でHTMLやステートマシンの内容はかなり勉強しましたが、実際に使うには程遠いです。まずは選択部分から始めましょう。これは日常的に使用する場合により意味があると思われます。

最後に、私の Jsoup シリーズのブログとソース コードのアドレスを添付します: http://github.com/code4craft/jsoup-learning

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

&lt; datalist&gt;の目的は何ですか 要素? &lt; datalist&gt;の目的は何ですか 要素? Mar 21, 2025 pm 12:33 PM

この記事では、HTML&lt; Datalist&GT;について説明します。オートコンプリートの提案を提供し、ユーザーエクスペリエンスの改善、エラーの削減によりフォームを強化する要素。

&lt; Progress&gt;の目的は何ですか 要素? &lt; Progress&gt;の目的は何ですか 要素? Mar 21, 2025 pm 12:34 PM

この記事では、HTML&lt; Progress&gt;について説明します。要素、その目的、スタイリング、および&lt; meter&gt;との違い要素。主な焦点は、&lt; Progress&gt;を使用することです。タスクの完了と&lt; Meter&gt; statiの場合

&lt; meter&gt;の目的は何ですか 要素? &lt; meter&gt;の目的は何ですか 要素? Mar 21, 2025 pm 12:35 PM

この記事では、html&lt; meter&gt;について説明します。要素は、範囲内でスカラーまたは分数値を表示するために使用され、Web開発におけるその一般的なアプリケーション。それは差別化&lt; Meter&gt; &lt; Progress&gt;およびex

&lt; iframe&gt;の目的は何ですか タグ?使用する際のセキュリティ上の考慮事項は何ですか? &lt; iframe&gt;の目的は何ですか タグ?使用する際のセキュリティ上の考慮事項は何ですか? Mar 20, 2025 pm 06:05 PM

この記事では、&lt; iframe&gt;外部コンテンツをWebページ、その一般的な用途、セキュリティリスク、およびオブジェクトタグやAPIなどの代替案に埋め込む際のタグの目的。

ビューポートメタタグとは何ですか?レスポンシブデザインにとってなぜそれが重要なのですか? ビューポートメタタグとは何ですか?レスポンシブデザインにとってなぜそれが重要なのですか? Mar 20, 2025 pm 05:56 PM

この記事では、モバイルデバイスのレスポンシブWebデザインに不可欠なViewportメタタグについて説明します。適切な使用により、最適なコンテンツのスケーリングとユーザーの相互作用が保証され、誤用が設計とアクセシビリティの問題につながる可能性があることを説明しています。

HTML5フォーム検証属性を使用してユーザー入力を検証するにはどうすればよいですか? HTML5フォーム検証属性を使用してユーザー入力を検証するにはどうすればよいですか? Mar 17, 2025 pm 12:27 PM

この記事では、ブラウザのユーザー入力を直接検証するために、必要、パターン、MIN、MAX、および長さの制限などのHTML5フォーム検証属性を使用して説明します。

HTML5のクロスブラウザー互換性のベストプラクティスは何ですか? HTML5のクロスブラウザー互換性のベストプラクティスは何ですか? Mar 17, 2025 pm 12:20 PM

記事では、HTML5クロスブラウザーの互換性を確保するためのベストプラクティスについて説明し、機能検出、プログレッシブエンハンスメント、およびテスト方法に焦点を当てています。

HTML5&lt; time&gt;を使用するにはどうすればよいですか 日付と時刻を意味的に表す要素? HTML5&lt; time&gt;を使用するにはどうすればよいですか 日付と時刻を意味的に表す要素? Mar 12, 2025 pm 04:05 PM

この記事では、html5&lt; time&gt;について説明します。セマンティックデート/時刻表現の要素。 人間の読み取り可能なテキストとともに、マシンの読みやすさ(ISO 8601形式)のDateTime属性の重要性を強調し、Accessibilitを増やします

See all articles