# XML read Problem



## MarioK (24. Jun 2011)

Hallo Gemeinschaft,
ich habe folgendes XML Dokument vor mir liegen :
[XML]<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Knoten>
    <koordinaten id="0">
        <xkoord>111</xkoord>
        <ykoord>222</ykoord>
    </koordinaten>
    <koordinaten id="1">
        <xkoord>333</xkoord>
        <ykoord>444</ykoord>
    </koordinaten>
</Knoten>[/XML]

Erzeugt habe ich dieses damit : http://www.java-forum.org/xml-co/120551-xml-write-problem.html

Ich möchte nach dem Auslesen des XML Dokumentes eine ArrayList<Punkt> kreise erzeugt haben, die dann, wenn ich sie auslese folgenden Inhalt hat:
0(111,222)
1(333,444)

derzeit bekomme ich aber nur :
0(333,444)

mit dem folgenden Code habe ich es nicht geschafft:

```
import java.io.*;
import java.util.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;

public class PunkteXMLRead {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			XMLReader rd = XMLReaderFactory.createXMLReader();
			KoordinatenHandler ch = new KoordinatenHandler();

			rd.setContentHandler(ch);
			rd.parse("data/meinePunkte.xml");
			System.out.println("Es wurden folgende Knoten generiert:");
			ArrayList<Punkt> kreise = ch.getVertices();

			for (Punkt pkt: kreise) {
				System.out.println(pkt);
			}
		}
		catch (SAXException se) {
			System.out.println("SAX-Fehler: " + se.getMessage());
		}
		catch (IOException ioe) {
			System.out.println("Datei nicht gefunden");
			ioe.printStackTrace();
		}
	}
}

class KoordinatenHandler implements ContentHandler {
	private int xkoord, ykoord; // beinhaltet die zuletzt gelesene x- / y-Koordinate
	private int id; // beinhaltet die zuletzt gelesene id
	private boolean isXkoord = false; // true g.d.w. aktuelles Element vom Typ xkoord
	private boolean isYkoord = false; // true g.d.w. aktuelles Element vom Typ ykoord

	// Array mit Knoten, die aus XML-Dokument generiert wurden
	private ArrayList<Punkt> kreise;

	public ArrayList<Punkt> getVertices() {
		return kreise;
	}


	/**
	 * Methode, die bei Elementen vom Typ xkoord / ykoord das Attribut x / y mit
	 * dem Inhalt des Elementes belegt
	 */
	public void characters(char[] ch, int start, int length) throws SAXException {

		String s = (new String(ch, start, length)).trim(); // entfernt führende oder nachfolgende Whitespaces
		if (s.length() > 0) {
			if (isXkoord) {
				xkoord = new Integer(s);
			}
			else if (isYkoord) {
				ykoord = new Integer(s);
			}
		}

	}

	public void endElement(String namespaceURI, String localName, String qName) throws SAXException {

		if (localName.equals("koordinaten")) {
			kreise.add(new Punkt(id,xkoord,ykoord));
		}
		
	}
	
	/**
	 * Methode, die in Abhängigkeit vom Elementtyp die Klassenattribute isXkoord, isYkoord oder id belegt
	 */
	public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {

		if (localName.equals("xkoord")) { // aktuelles Element vom Typ xkoord
			isXkoord = true;
			isYkoord = false;
		}
		else if (localName.equals("ykoord")) { // aktuelles Element vom Typ ykoord
			isYkoord = true;
			isXkoord = false;
		}
		else if (localName.equals("koordinaten")) {
			isYkoord = false;
			isXkoord = false;
			kreise = new ArrayList<Punkt>();
		}
		else {
			isYkoord = false;
			isXkoord = false;
			if (localName.equals("koordinaten")) { // aktuelles Element vom Typ koordinaten
				// Wert des Attributs id des Knotens holen
				if (atts.getLength() != 1) {
					System.out.println("Falsches XML-Format");
					throw new RuntimeException("Falsches XML-Format");
				}
				else {
					if (atts.getLocalName(0).equals("id")) {
						id = new Integer(atts.getValue(0));
					}
					else {
						System.out.println("Falsches XML-Format: id");
						throw new RuntimeException("Falsches XML-Format");
					}
				}
			}
		}
	}
	

	public void endDocument() throws SAXException {}
	public void endPrefixMapping(String arg0) throws SAXException {}
	public void ignorableWhitespace(char[] arg0, int arg1, int arg2) throws SAXException {}
	public void processingInstruction(String arg0, String arg1) throws SAXException {}
	public void setDocumentLocator(Locator arg0) {}
	public void skippedEntity(String arg0) throws SAXException {}
	public void startDocument() throws SAXException {}
	public void startPrefixMapping(String arg0, String arg1) throws SAXException {}
}
```


1. mache ich mir das mit diesem Code zu schwer???
2. wo liegt mein Denkfehler??


----------



## eRaaaa (24. Jun 2011)

Du erstellst jedes mal eine neue Liste bei dem Start-Element 
	
	
	
	





```
koordinaten
```
, wieso?
Lösche mal Zeile 91
[c] kreise = new ArrayList<Punkt>();[/c]
bzw verschiebe die Instanziierung zu der Deklaration in Zeile 42 
private ArrayList<Punkt> kreise = new ArrayList<Punkt>();
bzw.
private List<Punkt> kreise = new ArrayList<Punkt>();

/edit: mal eben ausprobiert und noch einen Fehler entdeckt, deine IDs passen nicht. Das liegt daran dass du den else Teil falsch gesetzt hast, der Teil muss mit in die Abfrage nach dem Element koordinaten!

```
} else if (localName.equals("koordinaten")) {
			isYkoord = false;
			isXkoord = false;
			// Wert des Attributs id des Knotens holen
			if (atts.getLength() != 1) {
				System.out.println("Falsches XML-Format");
				throw new RuntimeException("Falsches XML-Format");
			} else {
				if (atts.getLocalName(0).equals("id")) {
					id = new Integer(atts.getValue(0));
				} else {
					System.out.println("Falsches XML-Format: id");
					throw new RuntimeException("Falsches XML-Format");
				}
			}
		}
```

und der else-Teil kann weg


----------



## MarioK (24. Jun 2011)

bevor ich zu deine Änderungen, an denen ich gerade arbeite, komme möchte ich noch kurz die Methode ins Rennen bringen, die ich vorher generiert hatte ... ist auch wesenlicher kürzer, aber es kommt immer nur null bzw Fehler einlesen bei raus. Ich suchte halt nach dem einfachen Weg, aber SAX scheint, ersteinmal in meinen Augen, doch komplexer zu sein.
Hier der Code : beachte dabei Zeile 26-30 und 61 -73 die fürs Einlesen zuständig sind
	
	
	
	





```
import javax.xml.bind.*;

import java.io.*;
import java.util.*;

public class PunkteXMLWrite {
		/**
		 * Methode zum Schreiben von Punkten in Datei im XML-Format
		 * @param punkteToXML die zu schreibenden Punkte
		 * @param file die Datei in die die Punkte im XML-Format geschrieben werden sollen
		 * @throws JAXBException
		 */
		public void writePunkteToXML(PunkteToXML punkteToXML, File file) throws JAXBException {
			JAXBContext jc = JAXBContext.newInstance(PunkteToXML.class);
			Marshaller m = jc.createMarshaller();
			m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
			m.marshal(punkteToXML, file);
		}
		
		/**
		 * Methode zur Rekonstuktion von Punkten aus einer Datei im XML-Format
		 * @param file die Datei mit Punkten im XML-Format
		 * @return ein Objekt mit den in file gelesenen Adressen
		 * @throws JAXBException
		 */
		public PunkteToXML readPunkteToXML(File file) throws JAXBException {
			JAXBContext jc = JAXBContext.newInstance(PunkteToXML.class);
			Unmarshaller u = jc.createUnmarshaller();
			return (PunkteToXML) u.unmarshal(file);
		}
		/**
		 * @param args
		 */
		public static void main(String[] args) {
			// TODO Auto-generated method stub
			PunkteXMLWrite meineDB = new PunkteXMLWrite();
			
			ArrayList<Punkt> kreise = new ArrayList<Punkt> ();
			kreise.add(new Punkt(0, 111, 222));			
			kreise.add(new Punkt(1, 333, 444));
			System.out.println(kreise);
			System.out.println();
			PunkteToXML meinePunkte = new PunkteToXML(kreise);
			
			/* Ausgabe der Liste mit Punkten */
			for (Punkt pkt: meinePunkte.getKreise()) {
				System.out.println(pkt);
			}
			
			// Generierung des XML-Dokumentes mit Punkten
			File f = new File("data/meinePunkte.xml");
			try {
				meineDB.writePunkteToXML(meinePunkte, f);
			}
			catch (Exception e) {
				System.out.println(e.getMessage());
				System.out.println("Fehler Auslesen");
			}
			
			// Rekonstruktion der Objekte aus der XML-Datei
			try {
				PunkteToXML meinePunkteNeu = meineDB.readPunkteToXML(f);
				kreise = meinePunkteNeu.getKreise();
			
				for (Punkt pkt: kreise) {
					System.out.println(pkt);
				}
			}
			catch (Exception e) {
				
				System.out.println(e.getMessage());
				System.out.println("Fehler Einlesen");
			}
		}
}
```


----------



## eRaaaa (24. Jun 2011)

Ah ja ok, wieso du das nicht direkt mit dem Unmarshaller gemacht hast habe ich mich eh schon gefragt!
Warum das aber nicht geht, liegt daran, dass es 
public void setKreise(ArrayList<Punkt> kreise) {
anstelle von 
public void setListe(ArrayList<Punkt> kreise) {
in PunkteToXML heißen muss


----------



## MarioK (24. Jun 2011)

ich probiere halt als Newbie in Punkto XML und Java halt viele Dinge aus ...

jedenfalls ein dickes Danke an dich .... es geht jetzt beides ... SAX und JAXB .... inwieweit ich das jetzt weiter nutzen kann, werde ich sehen ...


----------

