JAXB und konkrete Klassen erstellen

schnuffie

Erfahrenes Mitglied
Hallo Leute,

komme leider nicht mehr weiter.
Habe mit dem "javax.xml.bind.*"-Package (JAXB) zu tun.

Geschafft habe ich es bislang, die Beispiel-Sourcen generieren zu lassen. Das klappt.

Nun bekomme ich es leider nicht hin, via "unmarshall" mit ein Objekt geben zu lassen, das in der XML-Datei definiert ist.

Wer kann mir helfen? Bin am Verzweifeln. :confused:

Fehlermeldung:
javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"schoko"). Expected elements are <{http://example.org}schoko>,<{http://example.org}schokolade>
 

Anhänge

Hallo!

Ich hab das gleiche Problem gehabt bei meinen XML Experimenten. Ich hab damals vergessen darauf zu achten, dass mein XML File "valide" ist. Kann es vielleicht sein, dass du im XML File Verschachtelungen falsch gesetzt hast? (Ich hatte leider keine Zeit mir dein zip File näher anzusehn, deswegen nur ein schneller Tipp)

Gruß
TOM
 
Hallo!

meine beiden XML Files schauen so aus: (liegen im Verzeichnis xml relativ zum package root (von de.tutorials -> /de.... , /xml ...)
chocolate.xsd
Code:
 <?xml version="1.0" encoding="UTF-8"?>
 <xsd:schema	xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 	>
 	<xsd:element name="chocolates" type="chocolatesType"/>
 	<xsd:complexType name="chocolatesType">
 		<xsd:sequence>
 			<xsd:element name="chocolate" type="chocolateType" minOccurs="1"
 				maxOccurs="unbounded"/>
 		</xsd:sequence>
 	</xsd:complexType>
 	
 	<xsd:complexType name="chocolateType" >
 		<xsd:sequence>
 			<xsd:element name="flavour" type="xsd:string"/>
 			<xsd:element name="weight" type="xsd:string"/>
 			<xsd:element name="durableUtil" type="xsd:string"/>
 			<xsd:element name="price" type="xsd:string"/>
 		</xsd:sequence>
 		<xsd:attribute name="id" type="xsd:int"/>
 	</xsd:complexType>
 </xsd:schema>

chocolate.xml
Code:
  <?xml version="1.0" encoding="UTF-8"?>
 <chocolates>
 	<chocolate id="1">
 		<flavour>noisette</flavour>
 		<weight>100g</weight>
 		<durableUtil>2006-11-15</durableUtil>
 		<price>0.79</price>
 	</chocolate>
 	<chocolate id="3">
 		<flavour>ohne</flavour>
 		<weight>150g</weight>
 		<durableUtil>2007-06-14</durableUtil>
 		<price>0.99</price>
 	</chocolate>
 	<chocolate id="2">
 		<flavour>orange/zimt</flavour>
 		<weight>250g</weight>
 		<durableUtil>2005-12-24</durableUtil>
 		<price>1.19</price>
 	</chocolate>
 </chocolates>

Über xjc aus dem bin Verzeichnis der jaxb-Installation lasse ich mir über:
Code:
 E:\jwsdp\jaxb\bin>xjc E:\eclipse\3.1\eclipse\workspace\de.tutorials.jaxbexample\src\xml\chocolate.xsd
Die entsprechenden Klassen generieren:
Code:
 parsing a schema...
 compiling a schema...
 generated\impl\runtime\NamespaceContext2.java
 generated\impl\runtime\ValidatableObject.java
 generated\impl\runtime\UnmarshallingContext.java
 generated\impl\runtime\GrammarInfo.java
 generated\impl\runtime\AbstractUnmarshallingEventHandlerImpl.java
 generated\impl\runtime\XMLSerializable.java
 generated\impl\runtime\ValidationContext.java
 generated\impl\runtime\PrefixCallback.java
 generated\impl\runtime\SAXUnmarshallerHandlerImpl.java
 generated\impl\runtime\IdentityHashSet.java
 generated\impl\runtime\NamespaceContextImpl.java
 generated\impl\runtime\Util.java
 generated\impl\runtime\ValidatorImpl.java
 generated\impl\runtime\GrammarInfoImpl.java
 generated\impl\runtime\ValidatingUnmarshaller.java
 generated\impl\runtime\MarshallerImpl.java
 generated\impl\runtime\MSVValidator.java
 generated\impl\runtime\DefaultJAXBContextImpl.java
 generated\impl\runtime\UnmarshallingEventHandlerAdaptor.java
 generated\impl\runtime\SAXUnmarshallerHandler.java
 generated\impl\runtime\ErrorHandlerAdaptor.java
 generated\impl\runtime\UnmarshallableObject.java
 generated\impl\runtime\XMLSerializer.java
 generated\impl\runtime\UnmarshallerImpl.java
 generated\impl\runtime\ContentHandlerAdaptor.java
 generated\impl\runtime\InterningUnmarshallerHandler.java
 generated\impl\runtime\Discarder.java
 generated\impl\runtime\UnmarshallingEventHandler.java
 generated\impl\runtime\SAXMarshaller.java
 generated\impl\runtime\GrammarInfoFacade.java
 generated\impl\ChocolateTypeImpl.java
 generated\impl\ChocolatesImpl.java
 generated\impl\ChocolatesTypeImpl.java
 generated\impl\JAXBVersion.java
 generated\ChocolateType.java
 generated\Chocolates.java
 generated\ChocolatesType.java
 generated\ObjectFactory.java
 generated\bgm.ser
 generated\jaxb.properties
...da ich im Schema keinen eigenen TargetNamespace angegeben habe, landen alle Klassen standardmäßig im package generated...

Hier mein Beispiel Aufruf.
Code:
 /**
  * 
  */
 package de.tutorials;
 
 import java.util.Iterator;
 import java.util.List;
 
 import generated.ChocolateType;
 import generated.Chocolates;
 import generated.ObjectFactory;
 
 import javax.xml.bind.JAXBContext;
 
 /**
  * @author Tom
  * 
  */
 public class JAXBExample {
 
 	/**
 	 * @param args
 	 */
 	public static void main(String[] args) throws Exception {
 		JAXBContext jc = JAXBContext.newInstance("generated");
 		ObjectFactory objFactory = new ObjectFactory();
 		Chocolates chocolates = (Chocolates) objFactory.createUnmarshaller()
 				.unmarshal(
 		    		    JAXBExample.class.getClassLoader().getResourceAsStream(
 		    		    		"xml/chocolate.xml"));
 		List chocolateList = chocolates.getChocolate();
 		for (Iterator iter = chocolateList.iterator(); iter.hasNext();) {
 			ChocolateType chocolateType = (ChocolateType) iter.next();
 			System.out.println(chocolateType.getFlavour());
 		}
 	}
 
 }
Ausgabe:
Code:
 noisette
 ohne
 orange/zimt

Gruß Tom

Btw. ich hasse diese ewigen Namespace-Fummeleien...
 
Danke erstmal für Eure Hilfe.

Teppi:
Die Folien werde ich mir gleich mal anschauen.

Tom:
Du rufst mit xjc lediglich die xsd-Datei auf?
Bis auf Deine "Verenglischung" :) sieht das glatt wie mein Beispiel aus. Allerdings postest Du wesentlich mehr erstellte Dateien. (Was) habe ich an der Konfiguration (was) falsch gemacht? Ist das Mapping der Methoden in der bindng.xjb überflüssig?
 
Vom Projekt-Root im Eclipse starte ich die Klassengenerierung so:

HTML:
jaxb\bin\xjc.bat schoko.xsd -d src -p jaxb.schoko.generated

Erstellt werden dann diese Klassen:

HTML:
D:\projekte\workspace\JAXB>jaxb\bin\xjc.bat schoko.xsd -d src -p jaxb.schoko.generated
parsing a schema...
compiling a schema...
jaxb\schoko\generated\ObjectFactory.java
jaxb\schoko\generated\SchokoType.java
jaxb\schoko\generated\SchokoladeType.java
jaxb\schoko\generated\package-info.java

P.S.: Soviele Klassen wie bei Tom werden bei mir nicht erzeugt, auch nicht, wenn ich den Binding-Verweis (siehe Zip-Datei) jetzt weggelassen habe.
 
Irgendwie komme ich nicht weiter: Ein Verzeichnis "impl" und "impl.runtime" wird garnicht erst angelegt.

Muß ich nich spezielle JARs einbinden, vielleicht noch irgend einen Klassenpfad erstellen?
 
Hallo Leute,

Tom scheint mit einer anderen JAXB-Version zu arbeiten. Bei mir werden mit "binding.xjb" folgende Dateien erzeugt: (jaxb_erzeugte_sourcen.gif )

Schade, daß Keiner eine Idee hatte, woran mein Fehler liegen könnte. :( Die eigene Fehlersuche hat natürlich viel Zeit geschluckt, da mir einfach noch die Grundlagen zu JAXB fehlen. Danke an Teppi und Thomas, die mich einen Schritt weitergebracht haben. :)

Inzwischen habe ich es hinbekommen, die XML-Datei einzulesen:
HTML:
Enthaltene Schokoladen: 3
Nummer: 1
Geschmacksrichtung: noisette
Gewicht: 100g
Haltbarkeitsdatum: 2006-11-15
Preis: 0.79
Nummer: 3
Geschmacksrichtung: ohne
Gewicht: 150g
Haltbarkeitsdatum: 2007-06-14
Preis: 0.99
Nummer: 2
Geschmacksrichtung: orange/zimt
Gewicht: 250g
Haltbarkeitsdatum: 2005-12-24
Preis: 1.19

Bei mir fehlte der rot markierten Eintrag: :suspekt:
Code:
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
<steffen:schoko xmlns:steffen="http://example.org">
<schokolade nummer="1">
<geschmack>noisette</geschmack>
<gewicht>100g</gewicht>
<haltbar_bis>2006-11-15</haltbar_bis>
<preis>0.79</preis>
</schokolade>
<schokolade nummer="3">
<geschmack>ohne</geschmack>
<gewicht>150g</gewicht>
<haltbar_bis>2007-06-14</haltbar_bis>
<preis>0.99</preis>
</schokolade>
<schokolade nummer="2">
<geschmack>orange/zimt</geschmack>
<gewicht>250g</gewicht>
<haltbar_bis>2005-12-24</haltbar_bis>
<preis>1.19</preis>
</schokolade>
</steffen:schoko>

Über die generierte ObjectFactory kann ich auch den umgekehrten Weg gehen und vorhandene Objekte in XML-Form abspeichern.
 

Anhänge

  • jaxb_erzeugte_sourcen.gif
    jaxb_erzeugte_sourcen.gif
    2,4 KB · Aufrufe: 4.719
Zuletzt bearbeitet:
Zurück