実録、ともおじちゃん

典型的な客先常駐型ソフトウェア技術者の13年の軌跡

Android: tagsoup

2009年04月07日 | コンピュータ・家電
今年度作成するアプリケーションでWebViewで表示したページを解析しないといけないのですが、WebViewに表示中のページ(文字列、または、文書木)を取得するインタフェースがありません。

表示しているページのソースは、lexanderA: Extracting HTML from a WebViewを参考に取得することができますが、今度はHTMLを解析するプロセッサがありません。

そこで、tagsoupのプロジェクトHPからダウンロードしたtagsoup-1.2.jarをクラスライブラリに追加し、Showdown: JavaHTML Parser Comparisonに倣って Parser にSAXContentHandlerをセット。イザ、実行…あっけなく実装したContentHandlerの各メソッドが呼び出されました。

AndroidのAPIリファレンスを注意深く眺めていると、なんと、android.text.Htmltagsoupを使っていることを臭わせる一文が…

This uses TagSoup to handle real HTML, including all of the brokenness found in the wild.

だったら、APIとして公開してくれてもいいのに。

でも、まぁ、文書木(DOM)を構築するようにContentHandlerを実装しちゃえばいい訳だし、問題クリアかな。

最新の画像もっと見る

6 コメント

コメント日が  古い順  |   新しい順
Unknown (シノブ)
2010-06-17 15:00:24
こんにちは。初めてコメントいたします。

Android開発に参考にさせていただいております。

質問なのですが、、、文中に「Showdown: JavaHTML Parser Comparisonに倣って Parser にSAXのContentHandlerをセット」

っとありますが、具体的にはどの様な事をしたのでしょうか?

初心者過ぎて、初歩的過ぎる質問かもしれませんが、ご教授いただけると助かります。よろしくお願いいたします。
返信する
SAXは使ったことありますか?(Re: Unknown) (ともおじちゃん)
2010-06-17 21:36:52
gooブログではソースコードを整形することが難しいし、自宅に開発環境がないので、ヒントだけになってしまいます。すみません。

SAXを使ったことがあれば分かりやすいのですが、TagSoupのParserにDOMを構築するためのコンテントハンドラ (org.sax.xml.ContentHandlerを実装したクラスのインスタンス)をセットするだけです。ちょうど、"Showdown: JavaHTML Parser Comparison" で例示されたTagSoupのサンプルコードにあるSAX2DOMクラスがコンテントハンドラになります。

SAXパーサの使い方については、http://www.atmarkit.co.jp/fxml/rensai/xmljava04/xmljava02.html を参考にしてください。
返信する
Unknown (ゼロ)
2010-08-13 14:13:40
はじめまして
Android で HTML を処理できないかと検索し、この記事にたどり着いて大変助かりました
有意義な記事をありがとうございます


突然の質問、お赦しください
なぜか当方の環境では、DefaultHandler の startElement のみオーバーライド出来ない現象に悩まされています
startDocument などは正常にオーバーライドできており、動作もしています

何かお心当たりは無いでしょうか?
もしおわかりになりましたら、ご返信いただけると幸いです
お忙しい中、大変申し訳ありませんが、よろしくお願い致します
返信する
ちょっと調べてみます(Re: Unknown) (ともおじちゃん)
2010-08-16 00:16:54
すみません、1年以上前のことで忘れていますが、同じような現象があった気がします。

職場にまだソースが残っていると思いますので、確認してみます。
返信する
Re: ちょっと調べてみます(Re: Unknown) (ともおじちゃん)
2010-08-16 21:28:10
パーサに名前空間を扱うフィーチャー(feature)が有効になっていませんか?

わたしはこのフィーチャーを無効にしていました。

import org.ccil.cowan.tagsoup.Parser;
...

Parser parser = new Parser();
parser.setFeature(org.ccil.cowan.tagsoup.Parser.namespacesFeature, false);

どうでしょうか?
返信する
Unknown (ゼロ)
2010-09-03 11:12:03
返信が大変遅くなってしまい、申し訳ありません;
全く同じコードを新しいプロジェクトでつくり直すことで何故か問題が回避されました
原理は不明です

明確な解決法としてフィーチャーについて少し調べてみたいと思います


忙しい中、貴重なご意見をいただきありがとうございました!
返信する