DefaultMutableTreeNode do TreeML

0

Cześć,
mam problem. Otóż mam ładną strukturę drzewiastą stworzoną przy pomocy DefaultMutableTreeNode i chce ją sobie ładnie zwizualizować za pomocą biblioteczki Prefuse. Żeby nie robić sobie problemów, to stwierdziłem, że najłatwiej będzie zapisać moje drzewo do pliku typu TreeML (XML). (tu jest przykład: http://www.cs.umd.edu/hcil/iv03contest/datasets/treeml-sample.xml).

No i teraz szczerze mówiąc nie wiem jak sobie z tym poradzić, potrzebuje pomysł dzięki któremu wpakuje to drzewo do takiego pliku. Coś mi ostatnio myślenie nie idzie, wiem, że prawdopodobnie jest to proste :).

Dobrym sposobem by było przejść drzewo w PreOrder (http://pl.wikipedia.org/wiki/Przechodzenie_drzewa) ale dalej nie mam pomysłu jak zapisać to do pliku. Głównie chodzi o tagi zamykające gałęzie, nie wiem kiedy je tam wrzucać.

0

Może ci to pomoże to jest mój kod do drzewa z odczytem i zapisem do drzewa binarnego:


//Node Class
package pl.kaziuuu;

class Node<T>{
	private Node<T> left;
	
	private Node<T> right;
	
	private Node<T> before;
	
	private T inside;
	
	public Node(T inside){
		left=null;
		right=null;
		before=null;
		this.inside=inside;
	}

	public Node<T> getLeft() {
		return left;
	}

	public void setLeft(Node<T> left) {
		this.left = left;
	}

	public Node<T> getRight() {
		return right;
	}

	public void setRight(Node<T> right) {
		this.right = right;
	}

	public T getInside() {
		return inside;
	}

	public void setInside(T inside) {
		this.inside = inside;
	}

	public Node<T> getBefore() {
		return before;
	}

	public void setBefore(Node<T> before) {
		this.before = before;
	}
}

//Tree Class
package pl.kaziuuu;

import java.io.FileWriter;
import java.io.IOException;

public class Tree<T> {
	private final static int LEFT = 1;

	private final static int RIGHT = 2;

	private final static int NONE = 0;

	private Node<T> root;

	private Node<T> position;

	private static int howMany;

	private int howManyElements(Node<T> p) {
		if (p != null) {
			howManyElements(p.getLeft());
			howManyElements(p.getRight());
			howMany++;
		}
		return howMany;
	}

	private void printElements(Node<T> p) {
		if (p != null) {
			System.out.println(p.getInside());
			printElements(p.getLeft());
			printElements(p.getRight());
		}
	}

	private void writeToFile(Node<T> p, FileWriter fw, int side)
			throws IOException {
		if (p != null) {
			switch (side) {
			case NONE:
				fw.write("<node inside=\"" + p.getInside() + "\">\n");
				break;
			case LEFT:
				fw.write("<node inside=\"" + p.getInside()
						+ "\" type=\"left\">\n");
				break;
			case RIGHT:
				fw.write("<node inside=\"" + p.getInside()
						+ "\" type=\"right\">\n");
				break;
			}
			writeToFile(p.getLeft(), fw, LEFT);
			writeToFile(p.getRight(), fw, RIGHT);
			fw.write("</node>\n");
		}
	}

	private Node<T> find(String inside, Node<T> p) {
		Node<T> pointer;
		Node<T> pointer1;
		if (p != null) {
			if (p.getInside().equals(inside)) {
				return p;
			} else {
				pointer = find(inside, p.getLeft());
				pointer1 = find(inside, p.getRight());
				if (pointer == null && pointer1 == null) {
					return null;
				} else if (pointer == null) {
					return pointer1;
				} else {
					return pointer;
				}
			}
		} else {
			return null;
		}
	}

	public Tree() {
		root = null;
		position = null;
	}

	public Tree(Node<T> root) {
		this.root = root;
		position = root;
	}

	public int howManyElements() {
		howMany = 0;
		return howManyElements(root);
	}

	public void printElements() {
		printElements(root);
	}

	public Node<T> find(String inside) {
		return find(inside, root);
	}

	public void writeToFile(FileWriter fw) throws IOException {
		writeToFile(root, fw, NONE);
	}

	public void addLeft(Node<T> before, T inside) {
		if (root != null) {
			before.setLeft(new Node<T>(inside));
			before.getLeft().setBefore(before);
			position = before.getLeft();
		} else {
			root = new Node<T>(inside);
			position = root;
		}
	}

	public void addRight(Node<T> before, T inside) {
		if (root != null) {
			before.setRight(new Node<T>(inside));
			before.getRight().setBefore(before);
			position = before.getRight();
		} else {
			root = new Node<T>(inside);
			position = root;
		}
	}

	public void delete(Node<T> node) {
		if (node.getBefore() != null) {
			node.getBefore().setLeft(node.getLeft());
			node.getBefore().setRight(node.getRight());
			position = node.getBefore();
		} else {
			node = null;
			root = null;
			position = null;
		}
	}

	public Node<T> getRoot() {
		return root;
	}

	public Node<T> getPosition() {
		return position;
	}

	public void setPosition(Node<T> position) {
		this.position = position;
	}
}


//TreeXmlReader Class

package pl.kaziuuu;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class TreeXMLReader extends DefaultHandler{
	private Tree<String> tree;
	
	private ArrayList<String> treeException=new ArrayList<String>();
	
	private boolean haveTreeTag;
	
	private int level;	
	
	private HashMap<Integer,ArrayList<String>> mapNode=new HashMap<Integer,ArrayList<String>>();

	public TreeXMLReader(String fileName) throws ParserConfigurationException,
			SAXException, IOException {
		SAXParserFactory saxFactory = SAXParserFactory.newInstance();
		SAXParser saxParser = saxFactory.newSAXParser();
		saxParser.parse(new InputSource(fileName), this);
		level=0;
		haveTreeTag=false;
	}
	
	public void startElement(String uri, String localName,
	         String qName, Attributes atts) throws SAXException {
		String type=null;
		String inside=null;
		ArrayList<String> temp=null;
		if(qName.equalsIgnoreCase("tree")){
			if(level>0)
				treeException.add("\"tree\" must be first tag");
			if(haveTreeTag)
				treeException.add("Must have one \"tree\" tag");
			haveTreeTag=true;
		}
		if(!qName.equalsIgnoreCase("tree")&&!qName.equalsIgnoreCase("node")){
			treeException.add("\""+qName+"\" is not allowed tag");
		}
		if(qName.equalsIgnoreCase("node")){
			if(level==0){
				treeException.add("\"node\" hasn't been first tag");
			}else{
				
				for(int i=0;i<atts.getLength();i++){
					if(!atts.getQName(i).equalsIgnoreCase("inside")&&!atts.getQName(i).equalsIgnoreCase("type")){
						treeException.add("\""+atts.getQName(i)+"\" is not allowed properites of tag \"node\"");
					}else if(atts.getQName(i).equalsIgnoreCase("inside")){
						inside=atts.getValue(i);
					}else{
						type=atts.getValue(i);
					}
				}
				if(inside==null&&type==null){
					treeException.add("Node must have at least \"inside\" parameter");
				}else if(inside==null){
					treeException.add("Parametr \"inside\" must exist");
				}else if(type==null){
					if(level>1){
						treeException.add("Root element of tree isn't allowed here");
					}else{
						if(mapNode.get(level)==null){
							temp=new ArrayList<String>();
							temp.add("root");
							mapNode.put(level, temp);
							tree=new Tree<String>(new Node<String>(inside));
						}else{
							treeException.add("More than one root element in tree isn't allowed");
						}
					}
				}else{
					if(!type.equalsIgnoreCase("left")&&!type.equalsIgnoreCase("right")){
						treeException.add("\""+type+"\" is not allowed value of parameter \"type\"");
					}else{
						if(mapNode.get(level)==null){
							temp=new ArrayList<String>();
							temp.add(type);
							mapNode.put(level, temp);
							if(type.equalsIgnoreCase("left")){
								tree.addLeft(tree.getPosition(), inside);
							}else{
								tree.addRight(tree.getPosition(), inside);
							}
						}else{
							if(mapNode.get(level).size()==1){
								if(mapNode.get(level).get(0).equalsIgnoreCase(type)){
									treeException.add("Tree isn't have to "+type+" node");
								}else{
									if(type.equalsIgnoreCase("left")){
										tree.addLeft(tree.getPosition(), inside);
									}else{
										tree.addRight(tree.getPosition(), inside);
									}
									mapNode.get(level).add(type);
								}
							}else if(mapNode.get(level).size()==2){
								treeException.add("Tree isn't have more than two subelements");
							}
						}
					}
				}
			}
		}
		level++;
	}
	
	public void endElement(String uri, String localName,
	         String qName) throws SAXException {
		mapNode.put(level, null);
		if(tree.getPosition().getBefore()!=null){
			tree.setPosition(tree.getPosition().getBefore());
		}
		level--;
	}
	
	public Tree<String> getTree() throws TreeXMLException{
		String temp="";
		if(treeException.isEmpty()){
			return tree;
		}else{
			for(String s:treeException){
				temp+=s+"\n";
			}
			throw new TreeXMLException(temp);
		}
	}
}


//TreeXMLWriter Class
package pl.kaziuuu;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class TreeXMLWriter {
	private Tree<String> tree;
	
	public TreeXMLWriter(Tree<String> tree){
		this.tree=tree;
	}
	
	public void write(String fileName) throws IOException{
		FileWriter file = new FileWriter(new File(fileName), true);
		file.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
		file.write("<!DOCTYPE tree SYSTEM \"tree.dtd\">\n<!--tree definition-->\n<tree>\n");
		tree.writeToFile(file);
		file.write("</tree>");
		file.close();
	}
}
0

I przykładowy plik xml :)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tree SYSTEM "tree.dtd">
<!--tree definition-->
<tree>
	<node inside="a">
		<node inside="h" type="right">
			<node inside="b" type="left">
				<node inside="f" type="left"/>
				<node inside="g" type="right"/>
			</node>
			<node inside="c" type="right">
				<node inside="d" type="left"/>
				<node inside="e" type="right"/>
			</node>
		</node>
		<node inside="i" type="left">
			<node inside="j" type="left">
				<node inside="k" type="left"/>
				<node inside="l" type="right"/>
			</node>
			<node inside="m" type="right">
				<node inside="n" type="left"/>
				<node inside="o" type="right"/>
			</node>
		</node>
	</node>
</tree>

1 użytkowników online, w tym zalogowanych: 0, gości: 1