[ Main Page ]

DOMとJTreeとの相互変換

最近ちょっとしたことで必要になったDOMとJTreeとの相互変換について、ちょっとしたものを作りました。

	// Very simple JTree <-> DOM converter

	import java.io.*;
	import javax.swing.tree.*;
	import org.w3c.dom.*;
	import javax.xml.parsers.*;

	import javax.xml.transform.*;
	import javax.xml.transform.dom.*;
	import javax.xml.transform.stream.*;

	/**
	   JTree内に保持されているconvert javax.swing.tree.DefaultMutableTreeNode
	   を保存/読み込みできるようにするためのorg.w3c.dom.Elementとの相互変換
	   のためのクラス。

	   例えば、以下のようなJTreeは下のようなDOMに変換されます。

	   root
	   a
	   b

	   <?xml version="1.0" encoding="utf-8"?>
	   <TreeNode tag="root">
	   <TreeNode tag="a"/>
	   <TreeNode tag="b"/>
	   </TreeNode>

	   また、下のDOMから上のようなDefaultMutaleTreeNodeを作成できます。
	   tag名と属性名はコンストラクタで設定可能です。
	*/

	public class TreeDOM
	{
	    private String attrName = null;
	    private String tagName = null;

	    TreeDOM()
	    {
	    this("tag", "TreeNode");
	    }

	    TreeDOM(String attr, String tag)
	    {
	    attrName = attr;
	    tagName = tag;
	    }

	    /**
	     * nodeからDefaultMutabletTreeNodeを作成。見た通り。
	     *
	     * @param node DOMのNode
	     */
	    public DefaultMutableTreeNode nodeToTreeNode(Node node)
	    {
	    DefaultMutableTreeNode treeNode = new DefaultMutableTreeNode();

	    NamedNodeMap map = node.getAttributes();
	    if (map == null)
	        return null;
	    Node n = map.getNamedItem(attrName);
	    if (n == null)
	        return null;
	    treeNode.setUserObject(n.getNodeValue());

	    if (node.hasChildNodes())
	        {
	        NodeList nodeList = node.getChildNodes();
	        for (int i = 0;i < nodeList.getLength();i ++)
	            {
	            DefaultMutableTreeNode childTreeNode = nodeToTreeNode(nodeList.item(i));
	            if (childTreeNode != null)
	                {
	                treeNode.add(childTreeNode);
	                }
	            }
	        }

	    return treeNode;
	    }

	    /**
	     * DefaultMutableTreeNodeからDOMのElementを作成。
	     *
	     * @param treeNode 変換元
	     */
	    public Element treeNodeToNode(DefaultMutableTreeNode treeNode)
	    {
	    Document document = null;
	    try
	        {
	        // DOM 作成
	        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
	        DocumentBuilder builder = factory.newDocumentBuilder(); 
	        DOMImplementation domImpl = builder.getDOMImplementation();
	        document = domImpl.createDocument("", tagName, null);
	        }
	    // あったら困る。
	    catch (javax.xml.parsers.ParserConfigurationException e)
	        {
	        return null;
	        }
	    Element el = treeNodeToNode(treeNode, document, document.getDocumentElement());
	    return (Element)el.getFirstChild();
	    }

	    /**
	     * 再帰の関数。documentでNodeを作ったり、タグを足したりするので、ちょっと
	     * 引数が多め。(改善の余地あり。)
	     *
	     * @param treeNode 変換するべき残っている子どもnode
	     * @param document Node, Attr作成用
	     * @param node 子どもを足すcurrent node
	     */
	    private Element treeNodeToNode(DefaultMutableTreeNode treeNode, Document document, Element node)
	    {
	    Element tagNode = document.createElement(tagName);
	    Attr attr = document.createAttribute(attrName);
	    attr.setValue((String)treeNode.getUserObject());

	    tagNode.setAttributeNode(attr);

	    node.appendChild(tagNode);

	    if (!treeNode.isLeaf())
	        {
	        for (int i = 0;i < treeNode.getChildCount();i ++)
	            {
	            DefaultMutableTreeNode childTreeNode =
	                (DefaultMutableTreeNode)treeNode.getChildAt(i);
	            Element n = null;
	            if (childTreeNode != null)
	                {
	                n = treeNodeToNode(childTreeNode, document, tagNode);
	                }
	            }
	        }
	    return node;
	    }
	}
	      
      
 <rindolf>  rbastic: now I'm working with C++.
 <rindolf>  rbastic: I found out that my project compiles really quickly.
 <rindolf>  rbastic: under 5 or 10 minutes on a P4-2.4GHz with 1 GB of
            RAM.
 <rindolf>  rbastic: maybe KDE is making g++ look bad.
 <rbastic>  rindolf: yeah, i'm not a big KDE fan
 <rindolf>  rbastic: actually I'm using KDE-3.5.8 here.
 <rindolf>  rbastic: I was talking about the compilation speed of KDE apps
            and KDE itself.
 <rindolf>  rbastic: possibly because each file has half-a-gazillion
            headers.
 <rindolf>  My C++ code is a server one, so we don't have too many deps.
 <rbastic>  yeah, isn't there a way to cache header files? ie. in their
            "compiled" form?
 <rbastic>  or is that something I'm remembering from some other
            programming language that purported to build on top of C?
 <rindolf>  rbastic: MSVC has that.
 <rbastic>  ahh, nods
 <rindolf>  rbastic: no, Visual C++ has precompiled headers.
 <rindolf>  rbastic: I remember that I kept deleting them.
 <rbastic>  yeah, couldn't remember
 <rbastic>  lol
 <rindolf>  Pascal compiles very quickly.
 <rindolf>  That's one of the things I enjoyed in Delphi.
 <rbastic>  ugh, the app i'm been maintaining in Java was originally a fat
            client/server desktop app, written in Delphi
 <rindolf>  rbastic: ah.
 <rbastic>  i remember booting up the old app for the first time, and
            being amazed at how slow it was
 <rbastic>  eventually, i had to duplicate a feature in the Java code and
            i wasn't sure how it was implemented before
 <rindolf>  rbastic: you mean the Java app is faster? :S
 <rbastic>  so being as i had no Delphi experience, and the newer Delphi
            environments made NO sense to me at all, i just opened up the
            SQL Server query analyzer
 <rbastic>  rindolf: yes, but only b/c the Delphi programmer was an idiot,
            issuing queries over and over again needlessly
 <rbastic>  rindolf: if you could've seen the MSSQL Performance Analyzer
            or whatever, it was basically just.. Query1, Query2, Query3,
            Query1, Query2, Query3, repeat.
 <rbastic>  it was probably the worst ive ever seen in my life.. belongs
            on www.thedailywtf.com

    -- Can I haz a fast compiler
    -- #perl, Freenode

Never give an inch!


Powered by UNIX fortune(6)
[ Main Page ]