Frage

Der Versuch, eine Klasse Guss Ausnahme zu erhalten hier:

FooClass fooClass = (FooClass ) unmarshaller.unmarshal(inputStream);

wirft diese Ausnahme:

java.lang.ClassCastException: javax.xml.bind.JAXBElement

Ich verstehe das nicht - wie die Klasse durch das xjc.bat Werkzeug erzeugt wurde - und die Klassen, die es erzeugt habe ich überhaupt nicht verändert - so sollte es keine Gießproblemen hier sein - die Unmarshaller mir wirklich werden geben sollen zurück eine Klasse, die zu FooClass gegossen werden kann.

Alle Ideen, was ich tue falsch?

War es hilfreich?

Lösung

Hat FooClass die XmlRootElement Anmerkung haben? Wenn nicht, versuchen Sie:

Source source = new StreamSource(inputStream);
JAXBElement<FooClass> root = unmarshaller.unmarshal(source, FooClass.class);
FooClass foo = root.getValue();

Das ist auf der inoffizielle JAXB Führer .

Andere Tipps

Mit JAXBIntrospector auf der JAXBElement die schemaObject zu bekommen wie >>

JAXBContext jaxbContext = JAXBContext.newInstance(Class.forName(className));
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
Object schemaObject = JAXBIntrospector.getValue(unmarshaller.unmarshal(new ByteArrayInputStream(xmlString.getBytes())));

Siehe: wenn tut JAXB unmarshaller.unmarshal gibt eine JAXBElement oder ein MySchemaObject?

Ich lief in das gleiche Problem heute, sah hier die Antworten, tat etwas Forschung und ich sehe, dass die allgemeinste Lösung zu verwenden ist JAXBIntrospector . Daher -

FooClass fooClass = (FooClass ) unmarshaller.unmarshal(inputStream);

sollten geschrieben werden

FooClass fooClass = (FooClass) JAXBIntrospector.getValue(unmarshaller.unmarshal(inputStream));

oder noch besser, macht es allgemeinere -

T t = (T) JAXBIntrospector.getValue(unmarshaller.unmarshal(inputStream));

Für eine ausführlichere Erklärung lesen dieser Artikel . Es stellt sich heraus, dass Ihre XSD müssen richtig eingestellt werden, das heißt, es muss ein Root-Element sein, umfasst alle anderen Elemente.

  

XJC nicht versuchen @XmlRootElement Anmerkung auf einer Klasse zu setzen, die wir von einem komplexen Typ zu erzeugen. Der genaue Zustand ist etwas hässlich, aber die Grundidee ist, dass, wenn wir statisch, dass ein komplexer Typ garantieren kann nicht durch mehrere unterschiedliche Variablennamen verwendet werden, wir @XmlRootElement setzen.

würde ich in der XML-Datei suchen und sicherstellen, dass es grob ist, was Sie erwarten zu sehen.

Ich würde auch vorübergehend den Code ändern:

Object o = unmarshaller.unmarshal(inputStream);
System.out.println(o.getClass());

Wenn die erste failes dann die Klasse Besetzung innerhalb der Abstellungs Methode geschieht, wenn es gelingt, dann können Sie die aktuelle Klasse sehen, die Sie immer wieder und dann herausfinden, warum ist es nicht, was Sie erwarten, dass es sein.

Wir haben zu viele Stunden mit der JAXB Factory-Klasse fidgeting die Unmarshaller zu befriedigen. Wir haben gelernt, dass die Unmarshaller mit ohne Aufruf der JAXB-generierte Objekt Fabrik in Ordnung funktioniert. Hoffe, dass der Beispielcode jemand Frustration einlöst:

System.out.println("Processing generic-type unmarshaller: ");
MessageClass mcObject = unmarshalXml(MessageClass.class, msgQryStreamSource,
    NAMESPACE + "." + "MessageClass");

public static <T> T unmarshalXml(Class<T> clazz, StreamSource queryResults,
    String contextNamespace)
    {
        T resultObject = null;
        try {
            //Create instance of the JAXBContext from the class-name
            JAXBContext jc;
            jc = JAXBContext.newInstance(Class.forName(clazz.getName()));
            Unmarshaller u = jc.createUnmarshaller();
            resultObject = clazz.cast(u.unmarshal(queryResults));
            }
              //Put your own error-handling here.
        catch(JAXBException e)
        {
            e.printStackTrace();
        }
        catch (ClassCastException e)
        {
            e.printStackTrace();
        }
        catch (ClassNotFoundException e)
        {
            e.printStackTrace();
        }
        return clazz.cast(resultObject);
    }

Aufbauend auf den Vorschauen Antworten von Kollegen, falls jemand noch auf die Suche nach einer Antwort.

hatte ich die Frage der das Wurzelelement meines Schema mit wird wie folgt definiert:

<schema>
  <element name="foo" type="bar" />
  <complexType name="bar" />
</schema>

Und deshalb war ich ein Cast Exception auf immer:

try {            
        javax.xml.bind.JAXBContext jaxbCtx = javax.xml.bind.JAXBContext.newInstance(mobilityConfigType.getClass().getPackage().getName());            
        javax.xml.bind.Unmarshaller unmarshaller = jaxbCtx.createUnmarshaller();
        File f = FileUtil.toFile(this.getPrimaryFile());            
        mobilityConfigType = (MobilityModelConfigType)unmarshaller.unmarshal(FileUtil.toFile(this.getPrimaryFile()));
    } catch (javax.xml.bind.JAXBException ex) {            
        java.util.logging.Logger.getLogger("global").log(java.util.logging.Level.SEVERE, null, ex); //NOI18N
    }

Was ich tat, war die erste Zeile der try-Blöcke zu ändern:

javax.xml.bind.JAXBContext jaxbCtx = javax.xml.bind.JAXBContext.newInstance(mobilityConfigType.getClass().getName());

, dass das Problem für mich gelöst.

Sind Sie absolut sicher FooClass das Quelle Wurzelelement der XML-Eingabe ist, dass Sie es übergeben? Unmarshall wird ein Objekt des Root-Elements zurückkehren, indem xjc erstellt.

Manchmal haben Sie eine XSD-Definition mit mehreren verschiedenen Stammelementen (zum Beispiel XSD in WSDL definiert) und in diesem Fall die generierten Klassen fehlen @XmlRootElement. So wie Benutzer mbrauh bereits geschrieben Sie haben den Wert von JAXBElement zu bekommen. In meinem Fall habe ich:

FooClass request = ((JAXBElement< FooClass >) marshaller.unmarshal(new StreamSource(classPathResource.getInputStream()))).getValue();

So Generika können Sie ganz einfach doppelt type casting vermeiden können.

Geben Sie @XmlRootElement (name = "specifyName", namespace = "Namespace"), um Objekt zu verwandeln.

Ich traf auch die diese sehr einfache Lösung „Javax.xml.bind.JAXBElement kann nicht gegossen werden“ Fehler und gefunden:

FooClass fooClass = (FooClass) ((JAXBElement) u.unmarshal(new File("xml/foo.xml")) ).getValue();

Da offenbar ein Objekt vom Typ JAXBElement zurückgegeben wird, müssen Sie den Wert stattdessen typisieren.

Quelle: https://forums.oracle.com/thread/1625944

Versuchen Sie folgendes:

JAXBContext jc = JAXBContext.newInstance(Foo.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
JAXBElement element = (JAXBElement) unmarshaller.unmarshal( new StringReader(xmlString));
Foo foo = (Foo)element;

In meinem Fall habe ich den Fehler beim Versuch, eine Seife Petition von der SOAPUI Anwendung zu senden. Ich muss die Eigenschaft ‚Strip Whitespaces‘ auf true setzen, diesen Fehler zu überspringen.

Wenn debuggen den Inhalt erhalten hat, ist eine Liste mit dem nächsten Inhalt:

[0] = "\n"
[1] = JAXBElement
[2] = "\n"

Hope jemand helfen.

Wenn Sie Zugriff und Sie können die XSD ändern. Für mich hängt das Problem, wenn ich die XSD von XML mit IDEA erzeugen.

Mit diesem xml:

<?xml version="1.0"?>
<schema>
  <element name="foo" type="bar" />
  <complexType name="bar" />
</schema>

IDEA ein XSD wie die Erzeugung und JAXB wird ein Wurzelelement nicht erzeugen:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="schema" type="schemaType"/>
  <xs:complexType name="schemaType">
    <xs:sequence>
      <xs:element type="elementType" name="element"/>
      <xs:element type="complexTypeType" name="complexType"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="elementType">
    <xs:simpleContent>
      <xs:extension base="xs:string">
        <xs:attribute type="xs:string" name="name"/>
        <xs:attribute type="xs:string" name="type"/>
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>
  <xs:complexType name="complexTypeType">
    <xs:simpleContent>
      <xs:extension base="xs:string">
        <xs:attribute type="xs:string" name="name"/>
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>
</xs:schema>

Aber, wenn Sie die XSD auf diese Weise ändern (ändern Sie Ihr Root-Element „Schema“, um die zu bekommen xs: complex in dem Tag xs: element):

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="schema">
    <xs:complexType>
      <xs:sequence>
        <xs:element type="elementType" name="element"/>
        <xs:element type="complexTypeType" name="complexType"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:complexType name="schemaType">
    <xs:sequence>
      <xs:element type="elementType" name="element"/>
      <xs:element type="complexTypeType" name="complexType"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="elementType">
    <xs:simpleContent>
      <xs:extension base="xs:string">
        <xs:attribute type="xs:string" name="name"/>
        <xs:attribute type="xs:string" name="type"/>
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>
  <xs:complexType name="complexTypeType">
    <xs:simpleContent>
      <xs:extension base="xs:string">
        <xs:attribute type="xs:string" name="name"/>
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>
</xs:schema>

JAXB wird das Wurzelelement generieren!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top