czytanie dokumentu XML, problem

0

Witam,

chce sobie napisac program w javie ktory bedzie mi parsowal pliki xml, problem w tym ze nie moge sobie poradzic z rekurencyjnym wywolywaniem metody do zczytywania elementow w pliku xml,

generalnie plik xml wyglada nastepujaco:

<ObjectRepository>
  <objects>
    <object class="javaclass" name="window">
      <bleble></bleble>
      <childobject>
        <object class="javaclass" name="menu">
          <bleble></bleble>
          <childobject />
        </object>
        <object class="javaclass" name="frame">
          <bleble></bleble>
          <childobject>
            <object class="javaclass" name="panel">
              <bleble></bleble>
              <childobject>
                <object class="javaclass" name="button">
                  <bleble></bleble>
                  <childobject />
                </object>
                <object class="javaclass" name="textbox">
                  <bleble></bleble>
                  <childobject />
                </object>
              </childobject>
            </object>
          </childobject>
        </object>
      </childobject>
    </object>
  </objects>
</ObjectRepository>

jak widzicie xml sklada sie z:

<object class="" name="">
      <bleble></bleble>
      <childobject/>
</object>

ktory moze zawierac takie same obiekty w <childobject>

Czy moglby mi ktos pomoc jak w latwy sposob dynamicznie czytac takiego XMLa i budowac z niego JTree

z gory dziekuje z odpowiedz :)
pozdrawiam
Przemek

0

Zacznijmy od tego, że chcesz stworzyć coś co tłumaczy dokument XML na model DOM (lub bardzo podobny).
Masz dwa wyjścia:

  1. użyć parsera SAX (Simple API for XML), który ma takie metody jak startElement, endElement i przetwarza dokument jak strumień zdarzeń. W ten sposób działa większość narzędzi DOM.
  2. napisać parser, który będzie wstępnie wykonywał takie działania jak SAX. Algorytm wykorzystywał by stos i działał mniej więcej tak:
  • pierwszy znacznik otwierający, sprawdź typ i odłóż na stos informację o otwarci elementu
  • parsuj element
  • jeżeli kolejny znacznik otwierający to odłóż go na stos
  • jeżeli wartość to przypisz do elementu
  • jeżeli element zamykający to zamknij gałąź i zdejmij ze stosu informację o ostatnim otwartym elemencie.
0

Podstawowa sprawa to jest taka, czy chcesz pisać własny parser XML, czy użyć gotowych narzędzi. Z gotowych narzędzi, to akurat w tym przypadku ja zrobiłbym to używając biblioteki JDOM. Otrzymasz wtedy dokument XML w postaci drzewa obiektów jawy. Teraz wystarczy, że napiszesz implementację modelu dla JTree, który będzie korzystał z tego drzewa. Nie wiem tylko co masz na myśli pisząc "dynamicznie czytać takiego XMLa i budować z niego JTree". Ale to chyba też nie będzie problemem.

0

Masz przykład kod do wczytywania xml który zawiera drzewo binarne w formacie:

<?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>

A oto klasy:

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;

	}

}


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;

	}

}

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);

		}

	}

}

package pl.kaziuuu;



public class TreeXMLException extends Exception {

	public static final long serialVersionUID = 327837L;



	private String message;



	public TreeXMLException() {

		super();

	}



	public TreeXMLException(String message) {

		super(message);

		this.message = message;

	}



	public String getMessage() {

		return message;

	}



	public String toString(){

		return "Error parsing: \n"+message;

	}

}



// edit [koziolek]: Błagam popraw formatowanie
// Hmm... Ale co jest niby źle sformatowane ;>

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