Jsoup の公式説明では、重要な機能は整った HTML を出力することです。ここでは、Jsoup がどのように HTML を出力するかを見ていきます。
コードを分析する前に、「整った HTML」に実際に何が含まれているかを考えてみるとよいでしょう:
ここでは、HTML タグに関する知識を追加する必要があります。 HTML タグは、ブロックとインラインの 2 つのカテゴリに分類できます。タグのインラインとブロックの定義については、http://www.w3schools.com/html/html_blocks.asp を参照してください。Jsoup の Tag クラスは、Java 開発者にとって非常に優れた学習教材です。さらに、Jsoup の Entities クラスには、いくつかの HTML エンティティ エスケープ処理が含まれています。これらのエスケープされた対応データは、entities-full.properties および entities-base.properties に保存されます。
Jsoup フォーマットの実装
内部の継承と相互呼び出しの関係は少し複雑で、おそらく次のようになります:
Document.toString()=>Document.outerHtml()=>Element.html()、最後に Element.html()再びループします。すべての子要素に対して externalHtml() を呼び出し、それらを出力として結合します。
うわーそして、outerHtml() は、OuterHtmlVisitor を使用してすべての子ノードを走査し、結果としてそれらをアセンブルします。
// internal static initialisers:// prepped from http://www.w3.org/TR/REC-html40/sgml/dtd.html and other sources//block tags,需要换行private static final String[] blockTags = { "html", "head", "body", "frameset", "script", "noscript", "style", "meta", "link", "title", "frame", "noframes", "section", "nav", "aside", "hgroup", "header", "footer", "p", "h1", "h2", "h3", "h4", "h5", "h6", "ul", "ol", "pre", "div", "blockquote", "hr", "address", "figure", "figcaption", "form", "fieldset", "ins", "del", "s", "dl", "dt", "dd", "li", "table", "caption", "thead", "tfoot", "tbody", "colgroup", "col", "tr", "th", "td", "video", "audio", "canvas", "details", "menu", "plaintext"};//inline tags,无需换行private static final String[] inlineTags = { "object", "base", "font", "tt", "i", "b", "u", "big", "small", "em", "strong", "dfn", "code", "samp", "kbd", "var", "cite", "abbr", "time", "acronym", "mark", "ruby", "rt", "rp", "a", "img", "br", "wbr", "map", "q", "sub", "sup", "bdo", "iframe", "embed", "span", "input", "select", "textarea", "label", "button", "optgroup", "option", "legend", "datalist", "keygen", "output", "progress", "meter", "area", "param", "source", "track", "summary", "command", "device"};//emptyTags是不能有内容的标签,这类标签都是可以自闭合的private static final String[] emptyTags = { "meta", "link", "base", "frame", "img", "br", "wbr", "embed", "hr", "input", "keygen", "col", "command", "device"};private static final String[] formatAsInlineTags = { "title", "a", "p", "h1", "h2", "h3", "h4", "h5", "h6", "pre", "address", "li", "th", "td", "script", "style", "ins", "del", "s"};//在这些标签里,需要保留空格private static final String[] preserveWhitespaceTags = { "pre", "plaintext", "title", "textarea"};
OuterHtmlVisitor はすべての子ノードを走査し、node.outerHtmlHead() メソッドとnode.outerHtmlTail メソッドを呼び出します。
すごいですついに、実際に動作するコード、node.outerHtmlHead() とnode.outerHtmlTail を見つけました。 Jsoup の各ノードの出力メソッドは異なります。ここでは、Element と TextNode の 2 つの主要なノードについてのみ説明します。 Element は書式設定の主なオブジェクトであり、その 2 つのメソッド コードは次のとおりです:
private void html(StringBuilder accum) { for (Node node : childNodes) node.outerHtml(accum);}
そして ident メソッドのコードは 1 行だけです:
protected void outerHtml(StringBuilder accum) { new NodeTraversor(new OuterHtmlVisitor(accum, getOutputSettings())).traverse(this);}
コードはシンプルで明確で、多くを語る必要はありません。 StringUtil.padding() メソッドは、文字列の生成を減らすために、よく使用されるインデントを配列に保存することに注意してください。
さて、これで 1 つの記事です。次の記事では、より技術的なパーサーの部分について説明します。
さらに、このセクションの学習を通じて、StringBuilder に sb ではなく accum という名前を付けることを学びました。
このシリーズ: