最近生活が少し忙しくて、いつも夜中に起きていて精神状態があまり良くありません。仕事もうまくいきません。アイデアはたくさんありますが、コードほどうまくいかないものもあります。忘れてください、私はまだ正しい姿勢を持っています。結局のところ、私の資格はまだ若いので、私は私の資格を続けます。
Jsoup のソース コードを読むのは退屈ではありません。結局のところ、パーサーもクローラーの重要なコンポーネントの 1 つです。コードを読んだ後、多くのことを得ることができ、HTML の知識も向上しました。
ここで 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;}
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 タグには