NekoHTML サンプルをいじる

NekoHTMLの勉強をするためにサンプルを弄くって次のようなコードを書いた。

package example;

import org.apache.html.dom.HTMLDocumentImpl;
import org.cyberneko.html.parsers.DOMFragmentParser;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Node;
import org.w3c.dom.html.HTMLDocument;

public class TestHTMLDOM {

	public static void main(String[] argv) throws Exception {

		DOMFragmentParser parser = new DOMFragmentParser();
		HTMLDocument document = new HTMLDocumentImpl();
		DocumentFragment fragment = document.createDocumentFragment();
		parser.parse(argv[0], fragment);
		print(fragment, "");
	}

	private static void print(Node node, String indent) {

		switch (node.getNodeType()) {
			case Node.DOCUMENT_FRAGMENT_NODE:
			case Node.ELEMENT_NODE:
				System.out.println(indent + "<" + node.getNodeName() + ">");
				break;
			case Node.TEXT_NODE:
				String value = node.getNodeValue().trim();
				System.out.print(!value.equals("") ? indent + "[" + value + "]\n" : "");
				break;
			default:
				System.out.println("??");
				break;
		}
		
		if (node.hasAttributes()) {
			for (int i = 0; i < node.getAttributes().getLength(); i++) {
				printAttr(node.getAttributes().item(i), indent + "    ");
			}
		}
		
		if (node.hasChildNodes()) {
			for (int i = 0; i < node.getChildNodes().getLength(); i++) {
				print(node.getChildNodes().item(i), indent + "  ");
			}
		}
	}
	
	private static void printAttr(Node node, String indent) {

		String value = node.getNodeValue().trim();
		String name  = node.getNodeName();
		System.out.println(indent + name + " : " + value);
	}
}

例えば、http://coolstyle.dyndns.org/index.htmlを読み込むとこんな出力をする

<#document-fragment>
  <HTML>
      lang : ja
    <HEAD>
      <META>
          content : text/html; charset=utf-8
          http-equiv : content-type
      <LINK>
          href : common/style.css
          rel : stylesheet
          type : text/css
      <TITLE>
        [coolstyle]
    <BODY>
      <H1>
          class : title
        [coolstyle]
      <DIV>
          align : center
        <P>
          [誠にまことに汝らに告ぐ、]
        <P>
          [一粒の麦、地に落ちて死なずば、唯一つにて在らん。もし死なば、多くの実を結ぶべし。]
        <P>
          [己が生命を愛する者は、これを失い、]
        <P>
          [この世にてその生命を憎む者は、これを保ちて、永遠の生命に至るべし]
        <P>
          [(ヨハネの福音書 第12章23節〜25節)]
        <TABLE>
            border : 0
            summary : menu
            width : 480
          <TR>
            <TD>
              <A>
                  href : first/
                [はじめての方へ]
            <TD>
              <A>
                  href : opensource/
                [プログラミング]
            <TD>
              <A>
                  href : let'sbook/
                [本を読みましょう]
            <TD>
              <A>
                  href : http://d.hatena.ne.jp/coolstyle/
                [はてな日記]
      <HR>
      <DIV>
          align : right
        [是非是非ご意見お寄せください。気軽な感想をいただけたらうれしいです(^_^)]
        <ADDRESS>
          [yusuke-k-xxx@u01.gate01.com]

閉じタグではなくてインデントでレイアウトされたHTMLって良いね。