SAX XML

szmast3r

Mitglied
Hallo,

ich habe mich in meinem Projekt entschieden eine Datenhaltung mit XML zu machen. Nur weiß ich recht wenig über XML und habe mich mit Googlen etwas rein gefunden. Grundsätzlich verstehe ich XML, nur liegt es an dem Auslesen bzw. Rein schreiben. Es gibt recht viele Beispiele die alle hilfreich sind, nur gibt es wenig Beispiele, wie es mit schwierigeren XML aussieht, als nur eine Person auszulesen.

Hier die XML:
[XML]<?xml version="1.0"?>
<schluesselliste>
<schluessel id="0">
<sc>6030</sc>
<scname>Rentenbeginn/Leistungsart</scname>
<auspraegungen>
<auspraegung id="1">
<ausp>Leistungsart</ausp>
<von>015</von>
<bis>016</bis>
<auspbed>Altersrente fuer Frauen § 237a SGB6</auspbed>
<werte>
<wert id="2">
<name>01</name>
<bed>Keine Ahnung</bed>
</wert>
</werte>
</auspraegung>
</auspraegungen>
</schluessel>
</schluesselliste>[/XML]

Hier der Handler, der die XML Auslesen und die geforderten Daten Zwischenspeichern soll:
Java:
package de.deutscherv.testtool.controller;

import java.util.ArrayList;

import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;

import de.deutscherv.testtool.model.Auspraegung;
import de.deutscherv.testtool.model.Wert;
import de.deutscherv.testtool.model.XMLSchluessel;

public class SchluesselContentHandler implements ContentHandler{

	private String aktZeile;
	private ArrayList<XMLSchluessel> alleSchluessel = new ArrayList<XMLSchluessel>();
	private ArrayList<Auspraegung> auspraegungen = new ArrayList<Auspraegung>();
	private ArrayList<Wert> werte = new ArrayList<Wert>();
	private XMLSchluessel xmlSchluessel;
	private Auspraegung auspraegung;
	private Wert wert;
	private boolean checkVar = true;
	
	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		aktZeile = new String(ch, start, length);
	}

	@Override
	public void endDocument() throws SAXException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		if(localName.equals("sc")){
			xmlSchluessel.setnSc(aktZeile);
		}
		if(localName.equals("scname")){
			xmlSchluessel.setSc(aktZeile);
		}
				if(localName.equals("ausp")){
					auspraegung.setBedeutung(aktZeile);
				}
				if(localName.equals("von")){
					auspraegung.setVon(aktZeile);
				}
				if(localName.equals("bis")){
					auspraegung.setBis(aktZeile);
				}
				if(localName.equals("auspbed")){
					auspraegung.setBedeutung(aktZeile);
				}
				if(localName.equals("name")){
				wert.setName(aktZeile);
				}
				if(localName.equals("bed")){
					wert.setBedeutung(aktZeile);
				}
				
				speichereWert(wert);
				if(werte != null && auspraegung != null)
					auspraegung.setWerte(werte);
				speichereAuspraegung(auspraegung);
				if(auspraegungen != null)
					xmlSchluessel.setAuspraegungen(auspraegungen);
				speichereXMLSchluessel(xmlSchluessel);
				System.out.println("Sc: " + xmlSchluessel.getSc() + " nSC: "+ xmlSchluessel.getnSc() + " ausp: "+ xmlSchluessel.getAuspraegungen());
				

	}
	
	private void speichereWert(Wert wert){
		if(wert != null){
			for (Wert checkWert : werte) {
				checkVar = checkWert.equals(wert) ? false : true;
			}
			if(checkVar){
				werte.add(wert);
				System.out.println("ich habe den Wert " + wert.getName() + " gespeichert!");
			}
		}
	}
	
	private void speichereAuspraegung(Auspraegung auspraegung){
		if(auspraegung != null){
			for (Auspraegung checkAusp : auspraegungen) {
				checkVar = checkAusp.equals(auspraegung) ? false : true;
			}
			if(checkVar){
				auspraegungen.add(auspraegung);
				System.out.println("ich habe die Ausprägung: " + auspraegung.getName() + " gespeichert!");
			}
		}
	}
	
	private void speichereXMLSchluessel(XMLSchluessel xmlSchluessel){
		if(xmlSchluessel != null){
			for (XMLSchluessel checkXML : alleSchluessel) {
				checkVar = checkXML.equals(xmlSchluessel) ? false : true;
			}
			if(checkVar){
				alleSchluessel.add(xmlSchluessel);
				System.out.println("ich habe den XMLSchlüssel: " + xmlSchluessel.getSc() + " gespeichert!");
			}
		}
	}

	@Override
	public void endPrefixMapping(String prefix) throws SAXException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void ignorableWhitespace(char[] ch, int start, int length)
			throws SAXException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void processingInstruction(String target, String data)
			throws SAXException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void setDocumentLocator(Locator locator) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void skippedEntity(String name) throws SAXException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void startDocument() throws SAXException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes atts) throws SAXException {
		if(localName.equals("schluessel")){
			xmlSchluessel = new XMLSchluessel();
			xmlSchluessel.setId(Integer.parseInt(atts.getValue("id")));
		}
		if(localName.equals("auspraegung")){
			auspraegung = new Auspraegung();
			auspraegung.setId(Integer.parseInt(atts.getValue("id")));
		}
		if(localName.equals("wert")){
			wert = new Wert();
			wert.setId(Integer.parseInt(atts.getValue("id")));
		}
		
	}

	@Override
	public void startPrefixMapping(String prefix, String uri)
			throws SAXException {
		// TODO Auto-generated method stub
		
	}

}

Ich habe an dem Code ziemlich viel rum probiert (viel aus verzweiflung). Dieser hat sich andauernd geändert mit wenig Erfolg oder garkein Erfolg... :/

Ausgabe:

Code:
ich habe den XMLSchlüssel: null gespeichert!
Sc: null nSC: 6030 ausp: []
Sc: Rentenbeginn/Leistungsart nSC: 6030 ausp: []
Sc: Rentenbeginn/Leistungsart nSC: 6030 ausp: []
Sc: Rentenbeginn/Leistungsart nSC: 6030 ausp: []
Sc: Rentenbeginn/Leistungsart nSC: 6030 ausp: []
Sc: Rentenbeginn/Leistungsart nSC: 6030 ausp: []
Sc: Rentenbeginn/Leistungsart nSC: 6030 ausp: []
Sc: Rentenbeginn/Leistungsart nSC: 6030 ausp: []
Sc: Rentenbeginn/Leistungsart nSC: 6030 ausp: []
Sc: Rentenbeginn/Leistungsart nSC: 6030 ausp: []
Sc: Rentenbeginn/Leistungsart nSC: 6030 ausp: []
Sc: Rentenbeginn/Leistungsart nSC: 6030 ausp: []
Sc: Rentenbeginn/Leistungsart nSC: 6030 ausp: []
Sc: Rentenbeginn/Leistungsart nSC: 6030 ausp: []

Mein Ziel bei der ganzen Geschichte ist, dass er einfach nur die Werte die er da hat in XMLSchlüssel speichern soll. XMLSchlüssel beinhaltet den namen und den numerischen namen (Rentenbeginn/Leistungsart und 6030) und eine ArrayList<Auspraegung>. Diese Liste beinhaltet name, von, bis, bedeutung und eine ArrayList<Wert>. Diese Liste beinhaltet name und bedeutung.

Habt ihr Tipps wie die ganze Geschichte laufen kann?

Danke im Vorraus
 
Zuletzt bearbeitet:

dzim

Top Contributor
Ich finde es gut, dass du es mit den "alten" Methoden versuchst, aber ich empfehle dir: Tu es nicht!

Es gibt eine Reihe von Bibliotheken die du dir besser anschauen solltest:

- Per Default im Java ist JAXB enthalten: JAXB - Tutorial
-- geht nicht auf Android!

- Auf Android *kann* man einen Pull Parser verwenden (also wieder der "alte" Weg), oder man verwendet zum Beispiel das Simple Framework: Simple 2.7.1

Bei beiden Frameworks ist es notwendig, dass du Modellklassen anlegst.
Wie das etwa aussieht, hab ich vorhin auch schon mal hier beschrieben: http://www.java-forum.org/1028301-post19.html
 

szmast3r

Mitglied
Danke für den Tipp mit der API! Das ist echt um ein Vielfaches einfacher!!

Aber wie funktioniert es da, dass jeder Schlüssel eine Liste von Ausprägungen (bis zu 50 Ausprägungen pro Schlüssel) hat und jede Ausprägung eine Liste von Werten (bis zu 200 Werte pro Ausprägung)? Das ist für mich leider noch nicht ersichtlich.

Anhand der XML die ich oben rein geschmissen habe sieht man vielleicht, wie ich es meine. Ein Beispiel mit einer solchen Verschachtelung hab ich leider noch nicht gefunden.

MfG

szmast3r
 

dzim

Top Contributor
Ein Beispiel gibt es auf der bereits zuvor verlinkten Seite (JaxB-Tutorials von Lars Vogel): JAXB - Tutorial

Seeeeeeehr viele Tutorials findest du hier: https://jaxb.java.net/tutorial/

Wichtig ist einfach: Du musst mehrere Modellklassen erstellen. Im Prinzip für jede Ebene im XML eine.
schluesselliste
enthält (unter anderen) eine Liste (?) von
schluessel
enthält (unter anderen)
auspraegungen
enthält eine Liste von
auspraegung
...

Ungefähr klar?
 

szmast3r

Mitglied
Das mit den Modellklassen habe ich verstanden und soweit auch realisiert.
Ich habe es ausprobiert (zur Verständnis) an der "Wert" Klasse, die nun eine Modellklasse ist. Damit hat alles geklappt und war alles verständlich. Aber irgendwie fehlt mir die Vorstellung wie das mit solchen verschachtelungen geht. :/ Ich setz mich da sofort mal ran und versuch das hinzubekommen.
Oder hast du eine einfache erklärung? In dem Beispiel gibs bei Books beispielsweise keine Verschachtelungen.. da fehlt mir der Ansatz. Dann sollte ich es eigentlich hin bekommen.

MfG
szmast3r
 

dzim

Top Contributor
Auszug einer möglichen Modellklasse Schluessel:
Java:
@XmlElementWrapper(name = "auspraegungen")
@XmlElement(name = "auspraegung")
private ArrayList<Auspraegung> auspraegungList;

public ArrayList<Auspraegung> getAuspraegungList() {
  if (auspraegungList == null) {
    auspraegungList = new ArrayList<Auspraegung>();
  }
  return auspraegungList;
}

Ich selbst habe meist noch eine Auspraegungen zwischengeschaltet, aber so wie oben beschrieben geht es laut dem ersten Link, den ich dir gab, wohl auch.
 

szmast3r

Mitglied
Habe es jetzt einigermaßen verstanden (nehme ich an). Jetzt schmeißt er einen Fehler womit ich nichts anzufangen weiß.. jedenfalls nicht auf anhieb.

Hier mal die meldung:
Code:
javax.xml.bind.JAXBException: class de.deutscherv.testtool.model.XMLSchluessel nor any of its super class is known to this context.
	at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getBeanInfo(Unknown Source)
	at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsRoot(Unknown Source)
	at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.write(Unknown Source)
	at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.marshal(Unknown Source)
	at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(Unknown Source)
	at de.deutscherv.testtool.run.main.main(main.java:90)

Dazu die Klassen:

XmlSchluessel:
Java:
package de.deutscherv.testtool.model;

import java.util.ArrayList;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(namespace = "de.deutscherv.testtool.model")
public class XMLSchluessel {
	private int id;
	private String nSc;
	private String sc;
	private ArrayList<Auspraegung> auspraegungen;

	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getnSc() {
		return nSc;
	}
	public void setnSc(String nSc) {
		this.nSc = nSc;
	}
	public String getSc() {
		return sc;
	}
	public void setSc(String sc) {
		this.sc = sc;
	}
	public ArrayList<Auspraegung> getAuspraegungen() {
		return auspraegungen;
	}
	public void setAuspraegungen(ArrayList<Auspraegung> auspraegungen) {
		this.auspraegungen = auspraegungen;
	}
	
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return "id = " + id + " || numeric Sc = " + nSc + " || Sc = " + sc + " || Ausprägungen: " + auspraegungen.toString();
	}
}

Auspraegung:
Java:
package de.deutscherv.testtool.model;

import java.util.ArrayList;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;

public class Auspraegung {
	private int id;
	private String name;
	private String von;
	private String bis;
	private String bedeutung;
	private ArrayList<Wert> werte;
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getVon() {
		return von;
	}
	public void setVon(String von) {
		this.von = von;
	}
	public String getBis() {
		return bis;
	}
	public void setBis(String bis) {
		this.bis = bis;
	}
	public String getBedeutung() {
		return bedeutung;
	}
	public void setBedeutung(String bedeutung) {
		this.bedeutung = bedeutung;
	}
	public ArrayList<Wert> getWerte() {
		return werte;
	}
	public void setWerte(ArrayList<Wert> werte) {
		this.werte = werte;
	}
}

Wert:
Java:
package de.deutscherv.testtool.model;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "de.deutscherv.testtool.model")
public class Wert {
	private int id;
	private String name;
	private String bedeutung;
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getBedeutung() {
		return bedeutung;
	}
	public void setBedeutung(String bedeutung) {
		this.bedeutung = bedeutung;
	}
}

Wenn ich bei Auspraegung und Wert die Annotations verwende, sagt er mir dass die in dieser Klasse nicht benutzt werden dürfen, daher habe ich die zum testen erstmal raus gemacht.

EDIT: Beim XmlRootElement bin ich mir noch sehr unsicher... Ist da vielleicht was faul?

MfG
szmast3r
 
Zuletzt bearbeitet:

dzim

Top Contributor
Soweit ich sehen kann, besitzt dein XML keinen Namespace, also weg damit.

Schluesselliste müsste dein XmlRootElement sein, die anderen benötigen diese Annotation nicht. Wenn, dann verwende die XmlElement-Annotation.

[c]@XmlRootElement(name = "de.deutscherv.testtool.model")[/c] ist total falsch. Im XML gibt es nur den "wert", hier müsste also so etwas wie [c]@XmlElement(name = "wert")[/c] stehen.
Aber eigentlich würde sich das aus der Definition in der Klasse "Auspraegung" schon ergeben (wenn du dort ein @XmlElement über der Varaible "private Wert wert;" angegeben hast).
 
Zuletzt bearbeitet:

szmast3r

Mitglied
Zur zeit ist ja das Beispiel was du mir gegeben hast so, dass nur ein Objekt davon gespeichert wird. Wie sieht es aus wenn da viele Schlüssel (schlüsselliste) in eine ArrayList<XMLSchluessel> gepackt werden sollen?

Und würde es auch gehen eine XML nicht immer neu zu schreiben, sondern einfach bestimmte daten hinzuzufügen oder zu entfernen? Ohne, dass der Rest angefasst wird?

MfG

szmast3r
 

szmast3r

Mitglied
Hab leider kein Bearbeiten Button gefunden :/
Nebenbei noch eine Frage: Wie kann man sich für Beiträge bedanken... Bei anderen Foren ist das immer unten, wo man hier Zitieren kann usw.

Ich verstehe das noch nicht ganz...

Ich speichere einen Schlüssel (komplett gefüllt mit allen Daten) weg und lese ihn anschließend wieder aus. Dh. er kann problemlos ArrayLists speichern und sie später wieder auslesen? Ich könnte jetzt zwar damit arbeiten, verstehe es aber noch nicht genau...

Hier einmal die generierte XML:
Code:
  <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> 
- <ns2:xmlSchluessel xmlns:ns2="schluesselliste">
- <auspraegungen>
  <bedeutung>bedeutung</bedeutung> 
  <bis>016</bis> 
  <id>0</id> 
  <name>Leistungsart</name> 
  <von>015</von> 
- <werte>
  <bedeutung>testbed</bedeutung> 
  <id>1</id> 
  <name>Hans</name> 
  </werte>
- <werte>
  <bedeutung>kot</bedeutung> 
  <id>1</id> 
  <name>PETA</name> 
  </werte>
  </auspraegungen>
- <auspraegungen>
  <bedeutung>bedeutung2</bedeutung> 
  <bis>0162</bis> 
  <id>1</id> 
  <name>Leistungsart2</name> 
  <von>0152</von> 
- <werte>
  <bedeutung>durchfall</bedeutung> 
  <id>1</id> 
  <name>Hans</name> 
  </werte>
- <werte>
  <bedeutung>kot</bedeutung> 
  <id>1</id> 
  <name>PETA</name> 
  </werte>
  </auspraegungen>
  <id>0</id> 
  <sc>Rentenbeginn/Leistungsart</sc> 
  <nSc>6030</nSc> 
  </ns2:xmlSchluessel>

Weiß er dann wirklich welcher Wert zu welcher Ausprägung und welche Ausprägung zu welchen Schlüssel gehört? Oder liest er einfach alle Ausprägungen/Werte ein die es gibt und packt die bei jedem Schlüssel rein?

Unmarshal gilt ja für das gesamte XML Dokument, was (nach meiner Verständnis) heißt, es wird einmal abgespeichert... in diesem Fall in ein XmlSchluessel Objekt. Aber da kann doch nur 1 Schlüssel drinn gespeichert werden und nicht 500+ so wie angedacht oder?
 
Zuletzt bearbeitet:

dzim

Top Contributor
Der Button ist im Normalfall rechts unter dem jeweiligen Post und es sollte gross "Danke" drauf stehen haben...

Was deine Liste angeht müsste dir ja im Moment selbst auffallen, dass das XML im Vergleich zu deinem ersten Post falsch ist. Dein generiertes XML beginnt mit einem Schlüssel. Damit kann auch eine Datei nur genau diesen Schlüssel enthalten. Was dir Fehlt ist das root-Element "schluesselliste". Du hast lediglich einen Namespace eingetragen (was hier eher wenig Zielführend ist).
Wrappe deinen Schlüssel in eine Modelklasse "XMLSchluesselListe", oder so, und ab geht's! :)

ach und zu der Frage, ob du nur Bereiche einer XML abändern kannst: Nein. Jedenfalls nicht mit JAXB oder ähnlichen Frameworks. Die schreiben die Datei jedes mal neu, auch wenn sich vielleicht nur ein Zeichen geändert hat.

Grundsätzlich aber rate ich dir, dich noch einmal etwas näher mit XML (und sowieso auch XML-Schemas) zu beschäftigen! Ich denke, dass einige deiner Probleme auch ein wenig daher rühren, dass du dich mit dem Thema noch nicht genügend auseinander gesetzt hast. Ok?
 

szmast3r

Mitglied
1. Hier gibs irgendwie kein Danke button :/

2. Das mit dem Namespace hab ich leider nicht gesehen und bin selbst davon ausgegangen name = geschrieben zu haben. Dummer Fehler von mir.

3. Soweit funktioniert jetzt alles. Eine kleine Sache stört mich noch, unzwar dass das Tag Schluesselliste durch die neue Modelklasse doppelt vorkommt... Alles laut Code logisch, nur falls ich irgendetwas versuche zu ändern kommen Fehler.. Wie geht das, dass es nur einmal da steht?

Habe ich überhaupt die Modelklasse richtig verstanden? Hier einmal der Code:
Java:
package de.deutscherv.testtool.model;

import java.util.ArrayList;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "schluesselliste")
public class XMLSchluesselliste{

	private ArrayList<XMLSchluessel> schluesselliste = new ArrayList<XMLSchluessel>();
	
	@XmlElementWrapper(name = "schluesselliste")
	@XmlElement(name = "schluessel")
	public ArrayList<XMLSchluessel> getSchluesselliste() {
		return schluesselliste;
	}

	public void setSchluesselliste(ArrayList<XMLSchluessel> schluesselliste) {
		this.schluesselliste = schluesselliste;
	}
}

Der Rest stimmt alles ! :) Danke für die Hilfe!!
 

dzim

Top Contributor
in dem Fall brauchst du die Annotation [c]@XmlElementWrapper(name = "schluesselliste")[/c] nicht.

Code:
@XmlRootElement(name = "schluesselliste") public class XMLSchluesselliste {                   -->   <schluesselliste>
@XmlElementWrapper(name = "schluesselliste")                                                          -->   <schluesselliste> <-- diese Zeile muss weg!
@XmlElement(name = "schluessel") public ArrayList<XMLSchluessel> getSchluesselliste() { -->   <schluessel>

Übrigens: Mach mal keinen Setter bei den Listen. Java selbst macht das beim generieren der Klassen aus einem Schema immer so hier:
Java:
    @XmlElement(name = "schluessel")
    public ArrayList<XMLSchluessel> getSchluesselliste() {
        if (schluesselliste == null) {
                // JAVA7:
                schluesselliste = new ArrayList<XMLSchluessel>();
                // JAVA8: schluesselliste = new ArrayList<>();
        }
        return schluesselliste;
    }

    // DURCH DEN GETTER IST HIER KEIN SETTER MEHR NOTWENDIG
 
Zuletzt bearbeitet:

szmast3r

Mitglied
Das geht ja eben nicht, dann bekommt er komischer weise eine IndexOutOfBound Exception .. Mit dieser Annotation geht es aber :/

Das mit dem Getter ist nicht schlecht und wusste ich auch so nicht. Kannte es nur so, dass man es bei getInstance() benutzt.
 

dzim

Top Contributor
Hier eine Testanwendung, bei der ich das verhalten selbst nachstelle:

Java:
import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

public class XMLTest {
	
	public static void main(String[] args) throws JAXBException {
		
		// the same two content nodes
		Content c1 = new Content();
		c1.setId("1");
		Content c2 = new Content();
		c2.setId("2");
		
		// a root with a list of content nodes
		Root root = new Root();
		root.getContentList().add(c1);
		root.getContentList().add(c2);
		
		// a root with a list of content nodes, wrapped into another root node
		RootWrap rootWrap = new RootWrap();
		rootWrap.getContentList().add(c1);
		rootWrap.getContentList().add(c2);
		
		// create JAXB context and instantiate marshaller
		JAXBContext context = JAXBContext.newInstance(Root.class);
		Marshaller m = context.createMarshaller();
		m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
		
		// Write to System.out
		m.marshal(root, System.out);
		
		System.out.println("\n=============================================\n");
		
		context = JAXBContext.newInstance(RootWrap.class);
		m = context.createMarshaller();
		m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
		
		// Write to System.out
		m.marshal(rootWrap, System.out);
	}
	
	@XmlRootElement(name = "root")
	@XmlType(name = "root", propOrder = { "contentList" })
	@XmlAccessorType(value = XmlAccessType.FIELD)
	public static class Root {
		
		@XmlElement(name = "content", required = true)
		private List<Content> contentList;
		
		public List<Content> getContentList() {
			if (contentList == null) {
				contentList = new ArrayList<>();
			}
			return contentList;
		}
	}
	
	@XmlRootElement(name = "root")
	@XmlType(name = "root", propOrder = { "contentList" })
	@XmlAccessorType(value = XmlAccessType.FIELD)
	public static class RootWrap {
		
		@XmlElementWrapper(name = "root")
		@XmlElement(name = "content")
		private List<Content> contentList;
		
		public List<Content> getContentList() {
			if (contentList == null) {
				contentList = new ArrayList<>();
			}
			return contentList;
		}
	}
	
	@XmlAccessorType(value = XmlAccessType.FIELD)
	public static class Content {
		
		@XmlAttribute(name = "id", required = true)
		private String id;
		
		public String getId() {
			return id;
		}
		
		public void setId(String id) {
			this.id = id;
		}
	}
}

Die Ausgabe des Programms ist die folgende:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
<content id="1"/>
<content id="2"/>
</root>

=============================================

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
<root>
<content id="1"/>
<content id="2"/>
</root>
</root>

Ich verwende eher
Code:
@XmlAccessorType(value = XmlAccessType.FIELD)
- damit annotiert man die variablen, nicht getter/setter - ich denke, dass daher vielleicht auch konzeptionelle Unterschiede bei uns im Kopf herrschen und meine Gedanken sich nicht 1:1 auf dein Problem mappen lassen :-D
 

szmast3r

Mitglied
Nach einer weile suchen ist mir ein sehr dummer Fehler aufgefallen. Er bekommt eine OutOfBoundException wenn ich die Annotation entferne, was keinen sinn gemacht hat.

Es lag daran dass er erst ausliest und dann die Datei nocheinmal neu schreibt.. Irgendwo logisch dass er dann nichts in die ArrayList speichern kann :D

Danke nochmal für den Einstieg in die API! :)

Damit wäre das Problem gelöst!! :D

MfG

szmast3r
 

Neue Themen


Oben