Problem JAXB - Komplettes XML in JTable auslesen

pregler

Grünschnabel
Hallo,

ich bin neu hier im Forum und auch neu in der Java-Welt. Ich habe ein Projekt zu stemmen, das ein xml-Dokument in eine Java-Applikation einlesen soll und in dieser als JTable anzeigbar ist. Ich habe das mit JAXB jetzt schon soweit hinbekommen, daß das Binding soweit funktioniert und die Klassen alle erstellt werden, aber ich kann immer nur das RootElement auslesen. Hier wurde diesbezüglich schon einmal etwas gepostet, was mir aber nicht wirklich weitergeholfen hat, weil mein xml-Schema recht umfangreich ausfällt.

Bekomme immer Fehlermeldung "cannot be cast..." - wäre schön, wenn mir da jemand weiterhelfen könnte.

Das xsd-und xml-File findet Ihr im Anhang.


Danke

cu
pregler
 

Anhänge

  • xsd_xml.zip
    6,3 KB · Aufrufe: 38
Poste doch bitte den relevanten Code und auftretende Exceptions hier direkt. Ich vermute nicht jeder hat Zeit und Lust in die Untiefen eines Zipfiles abzusteigen.

Eine ClassCastException ist allerdings recht eindeutig. Gelieferter Typ und erwarteter typ stimmen nicht überein. Im Allgemeinen hilft es, sich ausgeben zu lassen, was genau da zurückkommt um dem Fehler näherzukommen. Der Debugger ist dein Freund ;).

Gruß
Ollie
 
Hallo,

der XJC-Compiler hat mir folgende Klassen erstellt:

BoundsType.java
CopyrightType.java
EmailType.java
ExtensionsType.java
GpxType.java
LinkType.java
MetadataType.java
ObjectFactory.java
package-info.java
PersonType.java
PtsegType.java
...

Datei Parser.java mit Zugriff auf die Klassen:
Code:
try {
		
		
		
		 JAXBContext jc = JAXBContext.newInstance("gpx.jaxb");
		 Unmarshaller unmarshaller = jc.createUnmarshaller();
		 GpxType gpx = (GpxType) ((JAXBElement) unmarshaller.unmarshal(new FileInputStream("gpx/Rothaarsteig.gpx"))).getValue();
		 SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
	     Schema schema = schemaFactory.newSchema(new File("schema/gpx_xsd.xsd"));
	    
	     unmarshaller.setSchema(schema);
	     
	     System.out.println(gpx.getVersion());

Der Zugriff auf die Methode getVersion gelingt - das gpx-Element steht allerdings auch im Root der xml-Datei. Jetzt wollte ich Dir den Compilerfehler nochmal simulieren, aber jetzt meckert er gar nicht mehr (gibt's denn sowas)
Wenn ich jetzt allerdings ein Object einer anderen Klasse anlege, wie im Folgenden:

Code:
TrkType wpt = new TrkType();
System.out.println("Test: " + wpt.getTrkseg());
dann bekomme ich folgende Ausgabe: Test: [ ]

Du hattest in einem anderen Thread mal von traversieren gesprochen - vielleicht habe ich das ganze System noch nicht geschnallt...

cu
pregler
 
Nuja... der Code ist jetzt nich sooo hilfreich. Wichtig ist zu wissen, welche Klassen das @XmlRootElement tragen. Nur diese können dann auch das Rootelement in einem XML File sein. D.h. dein zu unmarshallendes File müsste als Rootknoten <gpx> oder sowas haben. Aber das scheint ja zu tun. Btw. den Cast auf JAXBElement kannst du dir sparen. Der Unmarshaller gibt direkte Roottypen zurück.

Warum du das Schema erst NACH dem Unmarshallen setzt ist mir schleierhaft ;).

Zum zweiten Codeteil: wenn du ein neues Objekt anlegst ist das leer. Das ist relativ logisch oder? Um an die tieferen Elemente zu kommen musst du halt einfach von Roottyp aus durchsteigen. Angenommen das XMl sieht so aus:
XML:
<gpx>
  <metadata />
  <link />
</gpx>
Dann kannst du mit gpx.getMetadata() an das darunterliegende Objekt kommen. Enthält Metadata wiederum Unterelemente bekommst du die indem du die Getter auf dem Type MetadataType aufrufst.

Das sollte allerdings ein Blick auf die Klassen ziemlich offensichtilich zeigen. Nachdem der Unmarshaller das Rootelement ausgespuckt hat sollte doch alles klar sein. Es sei denn, du kennst dein XML bzw, deine Klassen nicht ;).

REINHAUN!
 
Zuletzt bearbeitet von einem Moderator:
Hallo,

ich habe diesen Part mit dem JAXBElement rausgenommen:

Code:
GpxType gpx = (GpxType) unmarshaller.unmarshal(new FileInputStream("gpx/Rothaarsteig.gpx"));


und bekomme dann folgende Fehlermeldung ohne das ich irgendetwas anderes mache:

java.lang.ClassCastException: javax.xml.bind.JAXBElement cannot be cast to gpx.jaxb.GpxType
 
Dann ist das Rootelement deines XML wahrscheinlich nicht <gpx-type />. Schau doch einfach mal, was dir der Unmarshaller zurückgibt.

Gruß
Ollie
 
also entweder bin ich echt zu blöd dazu oder ich habe hier grundlegend noch was nicht verstanden...

mein Rootelement in der xml ist <gpx>

meine Klasse dazu heißt GpxType.java:

Code:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "gpxType", propOrder = {
    "metadata",
    "wpt",
    "rte",
    "trk",
    "extensions"
})
@XmlRootElement(name="gpx")
public class GpxType {

    protected MetadataType metadata;
    protected List<WptType> wpt;
    protected List<RteType> rte;
    protected List<TrkType> trk;
    protected ExtensionsType extensions;
    @XmlAttribute(required = true)
    protected String version;
    @XmlAttribute(required = true)
    protected String creator;
.....


meine xsd-Datei sieht folgendemaßen aus:

Code:
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.topografix.com/GPX/1/1" targetNamespace="http://www.topografix.com/GPX/1/1" elementFormDefault="qualified">
	<xsd:annotation>
		<xsd:documentation>
  GPX schema version 1.1 - For more information on GPX and this schema, visit http://www.topografix.com/gpx.asp

  GPX uses the following conventions: all coordinates are relative to the WGS84 datum.  All measurements are in metric units.
 </xsd:documentation>
	</xsd:annotation>
	<xsd:element name="gpx" type="gpxType">
		<xsd:annotation>
			<xsd:documentation>
		GPX is the root element in the XML file.
	  </xsd:documentation>
		</xsd:annotation>
	</xsd:element>
	<xsd:complexType name="gpxType">
		<xsd:annotation>
			<xsd:documentation>
		GPX documents contain a metadata header, followed by waypoints, routes, and tracks.  You can add your own elements
		to the extensions section of the GPX document.
	  </xsd:documentation>
		</xsd:annotation>
		<xsd:sequence>
			<xsd:element name="metadata" type="metadataType" minOccurs="0">
				<xsd:annotation>
					<xsd:documentation>
		Metadata about the file.
	   </xsd:documentation>
				</xsd:annotation>
			</xsd:element>
			<xsd:element name="wpt" type="wptType" minOccurs="0" maxOccurs="unbounded

......

</xsd:schema>

hier ein Auszug aus meiner XML-Datei:
Code:
<?xml version="1.0" standalone="yes"?>
<!-- Mit XMLSpy v2008 rel. 2 sp2 (http://www.altova.com) von Cyborg (EMBRACE) bearbeitet -->
<gpx xmlns="http://www.topografix.com/GPX/1/1" creator="www.ATLSoft.de GPSViewer" version="1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1">
	<trk>
		<name>9</name>
		<number>1</number>
		<trkseg>
			<trkpt lat="51.394300" lon="8.568190">
				<ele>0.0</ele>
				<type>Trackpoint</type>
			</trkpt>
			<trkpt lat="51.394440" lon="8.570560">
				<ele>0.0</ele>
				<type>Trackpoint</type>
			</trkpt>
			<trkpt lat="51.394180" lon="8.572860">
				<ele>0.0</ele>
				<type>Trackpoint</type>
.....

</trkseg>
	</trk>
</gpx>


und mein unmarshaler-Code:

Code:
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
	     Schema schema = schemaFactory.newSchema(new File("schema/gpx_xsd.xsd"));
		
		 JAXBContext jc = JAXBContext.newInstance("gpx.jaxb");
		 Unmarshaller unmarshaller = jc.createUnmarshaller();
		 GpxType gpx = (GpxType) unmarshaller.unmarshal(new FileInputStream("gpx/Rothaarsteig.gpx"));
		 
	     unmarshaller.setSchema(schema);

Wo liegt mein Fehler.....
 
Auch wenn es vielleicht schon etwas verspätet ist.
Hab eben ein ähnliches Problem bekommen. Meine Lösung:

das Ergebnis des unmarshallers in ein JAXBElement(z.B. bufEl) packen und das zielobject füllen mit:

Code:
zielObj=(ZielTyp)bufEl.getValue();

beste Grüße
FischkopfPa
 
Zurück