Java XML in Objekt umwandeln

nintendoluk

Commander
Registriert
Mai 2014
Beiträge
2.124
Hi zusammen,

ich will eine meiner XML-Dateien in ein Java-Objekt umwandeln. Das soll möglichst simpel /unkompliziert stattfinden, da ich mich daran nicht zu lange aufhalten will.

Meine XML-Datei sieht so aus:
Code:
<?xml version="1.0" encoding="UTF-8"?>
 <ITQuiz>
  <Quiz id="1">
    <Frage><![CDATA[Was ist eine Programmiersprache?]]></Frage>
    <Antwort id="1"><![CDATA[Java]]></Antwort>
    <Antwort id="2"><![CDATA[Soap]]></Antwort>
    <Antwort id="3"><![CDATA[Cobol]]></Antwort>
    <Ergebnis>A, C</Ergebnis>
  </Quiz>
  <Quiz id="2"> .........
.........
  <Quiz id="125">
    <Frage><![CDATA[Wie heißen die Baupläne für Objekte in der Objektorientierten Programmierung?]]></Frage>
    <Antwort id="1"><![CDATA[Klassen]]></Antwort>
    <Antwort id="2"><![CDATA[Blueprints]]></Antwort>
    <Antwort id="3"><![CDATA[Formen]]></Antwort>
    <Ergebnis>A</Ergebnis>
  </Quiz>
 </ITQuiz>

Der Bauplan für meine Objekte soll etwa so aussehen:
Code:
public class Quiz {
	String Frage;
	String[] Antwort = new String[3];
	String Ergebnis;
}

Nun habe ich nach Parsern gesucht und bin auf JAXB und XStream gestoßen. Diese sind jedoch etwas kompliziert und ich habe noch kein Beispiel gefunden, das meinem Vorhaben ähnelt.

Deshalb Frage ich euch was für mein Vorhaben am geeignetsten ist (kann auch gerne was anderes als JAXB oder XStream sein).
Wäre auch hilfreich wenn ihr bitte gleich noch ein jeweiliges Tutorial mitempfehlen könntet ^^

Bonusfrage:
Vielleicht ist euch aufgefallen, dass das Ergebnis (= Lösung) in meiner XML etwas ungünstig angegeben ist (Als Programmierer nur schwer verwertbar). Mir fällt jedoch auch keine bessere Möglichkeit ein.
Wenn ihr eine Möglichkeit kennt die Lösungen sauber anzugeben wäre ich euch sehr verbunden :-)
Dann bräuchte ich auch noch eine Möglichkeit, wie ich die 125 Ergebnisse automatisiert ins neue "Format" ändern könnte :P


Schonmal Danke & Schöne Grüße
Lukas :-)
 
Du kannst dir auch eine wsdl Datei erstellen und den Code generieren lassen und einbinden.
In meinen Projekten wird so über maven-build eine jar-Datei erzeugt, die in anderen Modulen per Maven Dependency eingezogen wird.
 
Zuletzt bearbeitet:
Hallo,
ich bin jetzt nicht mehr so der Java Crack, aber gibt es nicht die Möglichkeit aus dem XML Klassen bzw. Objekte zu deserialisieren?

Greetz
hroessler
 
Hier mal ein Beispiel:

java.io.Reader xmlReader = ...liest den Inhalt der xml
GENERATEDCLASS gen = carfin.common.serialization.JAXBFactory.deserializeObject(GENERATEDCLASS.class, xmlReader);

GENERATEDCLASS wird über maven-plugin aus der wsdl generiert und wird als Ergebnis von deseri... geliefert.
 
Dumme Frage - muss das XML so sein wie du es hier haben willst? Sonst würde ich dir den umgekehrten Weg vorschlagen - sprich du machst die Java Struktur wie sie dir passt und lässt dir daraus (mit JAXB oder XStream) ein XML (Schema) erzeugen.
 
Auch wenn ich jetzt nicht der Java Spezi bin denke ich das Hennis Vorschlag genau das richtige ist: Du kümmerst dich nur um die Klasse und überlasst einem Parser den In- und Export von bzw zu XML. Und ob das Array dann je Wert eine Zeile verbraucht oder nicht sollte dich nie interessieren.
Oder hast du vor die XML Dateien auch noch mit einem anderen Programm zu lesen?
Sofern das auch Java ist, wäre es am besten die Klassendatei zu sharen (link in Linux statt doppelte Datei?) und den selben Parser zu verwenden, damit beide Programme nen Im- und Export unterstützen.
 
Danke für eure Antworten,

ich hab jetzt die XML einfach mal "händisch" ausgelesen:

Code:
	public static ArrayList<Quiz> loadQuizList(String xml_path) throws SAXException, IOException, ParserConfigurationException {

		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = factory.newDocumentBuilder();
		Document document = builder.parse(new File(xml_path));

		ArrayList<Quiz> quizlist = new ArrayList<Quiz>();

		NodeList nodeList = document.getDocumentElement().getChildNodes();

		for (int i = 0; i < nodeList.getLength(); i++) {

			Node node = nodeList.item(i);

			if (node.getNodeType() == Node.ELEMENT_NODE) {

				Element elem = (Element) node;

				String question = elem.getElementsByTagName("Frage")
						.item(0).getChildNodes().item(0).getNodeValue();

				String[] answers = new String[3];
						
				answers[0] = elem.getElementsByTagName("Antwort").item(0)
								.getChildNodes().item(0).getNodeValue();			
				
				answers[1] = elem.getElementsByTagName("Antwort").item(1)
						.getChildNodes().item(0).getNodeValue();				
				
				answers[2] = elem.getElementsByTagName("Antwort").item(2)
						.getChildNodes().item(0).getNodeValue();

				String solution = elem.getElementsByTagName("Ergebnis")
						.item(0).getChildNodes().item(0).getNodeValue();

				quizlist.add(new Quiz(question, answers, solution));

				
			}

		}
		
		return quizlist;

	}

Ich denke jetzt werde ich Hennis Vorschlag nachgehen und aus dem dadurch entstandenen Quiz-Array eine XML zu parsen.

Jetzt ist noch die Frage offen: JAXB oder XStream? Was ist einfacher? Welches hat deutliche Vorteile?


Zum ablegen des Ergebnisses (Lösung) in der XML:
Ich hab mir überlegt, das als einzelne Zahl abzuspeichern hinter der sich 3 Bits verstecken (Wie bei Unix mit chmod also).
Also z.B.
7 = 111 (A,B,C ist richtig)
3 = 011 (B,C ist richtig)
6 = 110 (A,B ist richtig)

Macht das Sinn? Was meint ihr?

Habs jetzt so gelöst:

Code:
/*
 * 7	111	"C, B, A"
 * 6	110	"C, B"
 * 5	101	"C, A"
 * 4	100	"C"
 * 3	011	"B, A"
 * 2	010	"B"
 * 1	001	"A"
 */

for (Quiz quiz : myQuizList){ 
	
	quiz.solution = 0;
	
	if(quiz.old_solution.contains("A"))
	{
		quiz.solution = (byte) (1 + quiz.solution);
	}
	
	if(quiz.old_solution.contains("B"))
	{
		quiz.solution = (byte) (2 + quiz.solution);
	}
	
	if(quiz.old_solution.contains("C"))
	{
		quiz.solution = (byte) (4 + quiz.solution);
	}
	
	//verify
	if(quiz.solution < 1 || quiz.solution > 7)
	{
		System.err.println("mistake @ quiz " + quiz.question + " | " + quiz.old_solution + " is " + quiz.solution);
	}
	
}
 
Zuletzt bearbeitet:
JAXB ist ein Binding Framework und daher um einiges mächtiger als XStream, was "nur" eine Serialisierungs Bibliothek ist. Prinzipiell können aber beider deine Anforderungen erfüllen und letzten Endes musst du es selbst entscheiden.

Hier ein detaillierter Vergleich von XStream und JAXB anhand eines einfachen Beispiels.
http://blog.bdoughan.com/2010/10/how-does-jaxb-compare-to-xstream.html
 
Macht das Sinn? Was meint ihr?
Ich hab mir überlegt, das als einzelne Zahl abzuspeichern hinter der sich 3 Bits verstecken (Wie bei Unix mit chmod also)
Ich glaube du hast Hennis und meinen Vorschlag missverstanden:
Du sollst auf keinen Fall selbst überlegen wie du irgendwelche Datentypen in XML codiert und encodierst sondern diese komplette Intelligenz einer Serialisierungs-Bibliothek überlassen. Dh du programmierst dein Objekt einfach genau so wie du es in deinem Projekt benötigst und überlässt alles weitere dieser Bibliothek. Dh du wirst nie selbst eine XML parsen oder dir überlegen wie du bits&bytes in einer Datei abbildest.

In C++ mit Boost::serialize sieht das zB so aus um eine Klase die aus 3 Membern besteht zu serialisieren:
Code:
template<class Archive>
void serialize(Archive & ar, gps_position & g, const unsigned int version)
{
    ar & g.degrees;
    ar & g.minutes;
    ar & g.seconds;
}
Und ob das jetzt ne XML, ne TXT oder irgendeine binärkodierung wird ist eine einzige Konfiguration und betrifft deinen Quellcode in keinster Weise.
 
Zuletzt bearbeitet:
Mir ging es drum wie ich die Variable Lösung überhaupt angebe, damit ich mit ihr richtig arbeiten kann. Weil Strings vergleichen ist doch wirklich nicht unbedingt "best practice" ^^

Ich hab jetzt mit JAXB übrigens mein Objekt wieder in eine XML umgewandelt. Und die sieht eig. ganz lesbar aus:

Code:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<quizmaster>
    <quizDataList>
        <answers>Java</answers>
        <answers>Soap</answers>
        <answers>Cobol</answers>
        <question>Was ist eine Programmiersprache?</question>
        <solution>5</solution>
    </quizDataList>
    <quizDataList> .......
......
......
    </quizDataList>
</quizmaster>

Jetzt muss ich diese XML nur noch wieder mit JAXB auslesen und ich glaub ich schaff das alleine ;-)

Danke für eure ganze Hilfe!
 
Zurück
Oben