import java.io.*;
import java.net.*;
import javax.xml.parsers.*;
import org.xml.sax.*;
import org.w3c.dom.*;

// XML DOM Tree を表示するプログラム
// 使い方: java TreeViewer url [encoding]
//         (encoding は指定しないと utf-8)
// 
// URL例:
//  RSS ver.1.0: http://www.kanzaki.com/info/memo.rdf
//               http://manabekawori.cocolog-nifty.com/blog/index.rdf
//  RSS ver.2.0: http://blogmag.ascii.jp/kodera/index.xml

class DocumentTree {
    private URL url;
    private String encoding;
    private Document document;
    private int depth;
    public DocumentTree() {
        url = null;
        encoding = "utf-8";
        document = null;
        depth = 0;
    }
    public void setURL(String url) {
        try {
            this.url = new URL(url);
        }
        catch(IOException e) {
            System.err.println("間違ったURL: " + url);
        }
    }
    public void setEncoding(String encoding) {
        this.encoding = encoding;
    }
    /** URLで指示されたフィードを取得し DOM tree を構築 */
    public void connect() {
        BufferedReader in = null;
        try {
            // まずは接続し、データを読む Reader を生成
            URLConnection connection = url.openConnection();
            connection.connect();
            InputStream inputStream = connection.getInputStream();
            InputStreamReader reader = new InputStreamReader(inputStream,
                                                             encoding);
            in = new BufferedReader(reader);
        }
        catch (IOException e) {
            System.err.println("接続エラー: " + e);
            System.exit(1);
        }

        try {
            // Reader を使ってストリームを読み、それを解析して Document を生成
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            document = builder.parse(new InputSource(in));
        }
        catch (ParserConfigurationException e) {
            System.err.println("DocumentBuilderFactory生成エラー:" + e);
        }
        catch (SAXException e) {
            System.err.println("構文エラー:" + e);
        }
        catch (IOException e) {
            System.err.println("入出力エラー:" + e);
        }

        try {
            in.close();
        }
        catch (IOException e) {
            System.err.println("接続終了エラー: " + e);
        }
    }
    /** DOM Tree の内容を表示 */
    public void show() {
        try {
            // root要素を得る
            Element rootElement = document.getDocumentElement();
            String rootElementName = rootElement.getNodeName();
            System.out.println("root element: " + rootElementName);
            showTree(rootElement);
        }
        catch (DOMException e) {
            System.err.println("DOMエラー:" + e);
        }
    }
    /** node 以下の tree を表示 */
    private void showTree(Node node) {
        for(Node current = node.getFirstChild();
                 current != null;
                 current = current.getNextSibling()) {
            if(current.getNodeType() == Node.ELEMENT_NODE) { // ノードは要素?
                String nodeName = current.getNodeName();
                System.out.println(indent() + nodeName + " {");
                depth++;
                showTree(current); // さらに子ノードを見る (再帰)
                depth--;
                System.out.println(indent() + "}");
            }
            else if(current.getNodeType() == Node.TEXT_NODE // ノードはテキスト?
                    && current.getNodeValue().trim().length() != 0)
                System.out.println(indent() + current.getNodeValue());
            else if(current.getNodeType() == Node.CDATA_SECTION_NODE) // ノードはCDATA?
                System.out.println(indent() + current.getNodeValue());
                                                         // HTMLタグなどを含む
            else
                ; // 上記以外のノードでは何もしない
        }
    }
    private String indent() {
        String indent = "";
        for(int i = 0; i < depth; i++)
            indent += "  ";
        return indent;
    }
}

class TreeViewer {
    public static void main(String args[]) {
        DocumentTree tree = new DocumentTree();
        tree.setURL(args[0]);
        if(args.length > 1)  // 引数で指示があったら文字コードを指定
            tree.setEncoding(args[1]);
        tree.connect();
        tree.show();
    }
}