txqz memo

Mozilla Java Html Parserを使ってみた

マイコミジャーナルで紹介されていたのでMozilla Java Html Parserを触ってみたがうまくいかなかった。

SourceforgeからダウンロードしてMozillaHtmlParser.jarおよびlibフォルダに含まれていたJARファイル群をEclipseの「外部アーカイブ」に追加。以下のような簡単なソースを書いた (ていうかMozillaHtmlParser.jarの中に入っていたcom.dappit.Dapper.parser.example.ParserExampleをさらに簡単にしたもの):

import java.io.File;

import org.w3c.dom.Document;

import com.dappit.Dapper.parser.EnviromentController;
import com.dappit.Dapper.parser.MozillaParser;

public class Test {
    public static void main(String[] args) throws Exception {
        File parserLibraryFile = new File("./native/bin/MozillaParser" + EnviromentController.getSharedLibraryExtension());
        String parserLibrary = parserLibraryFile.getAbsolutePath();
        System.out.println("Loading Parser Library :" + parserLibrary);
        final File mozillaDistBinDirectory = new File("mozilla.dist.bin."+EnviromentController.getOperatingSystemName());
        MozillaParser.init(parserLibrary,mozillaDistBinDirectory.getAbsolutePath());        

        try {
            MozillaParser parser = new MozillaParser();
            System.out.println("parsing...");

            String html = "<html>Test</html>";
            Document document = parser.parse(html);
            System.out.println("Generated document :" + ((org.dom4j.Document)document).asXML());
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("done...");
    }
}

実行させると:

Operating system : Windows XP
Loading Parser Library :C:\\Program Files\\MozillaJavaHTMLParser\\native\\bin\\MozillaParser.dll
parsing...
Cannot convert: null into a W3C DOM Node
done...
Initializing XPCOM from location : C:\\Program Files\\MozillaJavaHTMLParser\\mozilla.dist.bin.win...
org.w3c.dom.DOMException: Not supported yet
    at org.dom4j.dom.DOMNodeHelper.notSupported(DOMNodeHelper.java:468)
    at org.dom4j.dom.DOMNodeHelper.asDOMNode(DOMNodeHelper.java:405)
    at org.dom4j.dom.DOMNodeHelper.getParentNode(DOMNodeHelper.java:79)
    at org.dom4j.dom.DOMElement.getParentNode(DOMElement.java:100)
    at com.dappit.Dapper.parser.DomDocumentBuilder.buildDocument(DomDocumentBuilder.java:109)
    at com.dappit.Dapper.parser.MozillaParser.parse(MozillaParser.java:84)
    at Test.main(Test.java:21)

DomDocumentBuilder.javaの109行目付近を見ると:

            case ParserInstruction.CloseNode:
            {
                if (currentElement == null)
                {
                    System.err.println("Error : Close Node where no OpenNode was called. trying to fix...");
                    // this.dump();
                }
                else if (closeHtml)
                    currentElement = (Element) currentElement.getParentNode();

変数currentElementはorg.w3c.Elementインターフェイスのインスタンスで、HTML要素の親ノードを取得しようとしたか、またはルートノードの親ノードを取得しようとしてNULLが出たのかなーと思ったが、まさかそんな基本的なところで躓くようなスクリプトが一般に公開されているとも思えないので私のやり方が悪いはず。でも見当がつかない。

Mozilla HTML Parserについて言及しているサイトを調べたが、bits and bytesの紹介記事 (直接Cから叩いている) とプログラム技術板の質問スレ (回答なし) くらいしか見当たらなかった。後者については、たしかにQuick Startには

Document domDocument = MozillaParser.getInstance().parse("<html>Hello world!</html>");
MozillaParser.getInstance().stopRunning();

なんて書いてあるからそうコーディングしてしまうけど、ちゃんとExampleファイルを見てみるとフツーにMozillaParserをnewしていたという……でもここを乗り越えると今私が嵌まっている罠が待っているわけで。誰かえらい人の降臨を待ちたいところ。

ちゃんとやったら動いた