2017-06-29 12 views
1

Dies ist eine Java JAXB Frage. Ich lese in einem Mixed-Content-Elemente von XML und versuche, es in einer anderen XML-Datei ausgegeben, aber wenn ich versuche, aus den Java-Klassen zu meiner XML-Ausgabe Marschall, bekomme ich folgende Fehlermeldung:Wie ordne ich einen Mixed-Content-Knoten an? Ich bekomme einen Marshal.Exception

[com.sun.istack.internal.SAXException2: class java.util.ArrayList nor any of its super class is known to this context. javax.xml.bind.JAXBException: class java.util.ArrayList nor any of its super class is known to this context.]

Die XML-Element, das das Problem verursacht, sieht wie folgt in dem Schema:

<xs:element name="manual_description"> 
    <xs:complexType **mixed="true"**> 
     <xs:sequence minOccurs="0"> 
     <xs:choice minOccurs="0" maxOccurs="unbounded"> 
      <xs:element ref="para"/> 
      <xs:group ref="docbook_elements"/> 
     </xs:choice> 
     </xs:sequence> 
    </xs:complexType> 
    </xs:element> 
... 
    <xs:group name="docbook_elements"> 
    <xs:choice> 
     <xs:element ref="note"/> 
     <xs:element ref="literal"/> 
     <xs:element ref="link"/> 
     <xs:element ref="itemizedlist"/> 
     <xs:element ref="informaltable"/> 
     <xs:element ref="emphasis"/> 
     <xs:element ref="subscript"/> 
     <xs:element ref="superscript"/> 
    </xs:choice> 
    </xs:group> 

Note: mixed="true"

ich das Schema in Eclipse laden und verwenden rechts~~POS=TRUNC> generieren> JAXB Klassen meiner Java-Klassen zu erhalten. Ich ändere diese Ausgabe nicht. Diese Klasse endet wie folgt aussehen:

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "", propOrder = { 
"content" 
}) 
@XmlRootElement(name = "manual_description") 
public class ManualDescription{ 

@XmlElementRefs({ 
    @XmlElementRef(name = "para", type = Para.class, required = false), 
    @XmlElementRef(name = "superscript", type = JAXBElement.class, required = false), 
    @XmlElementRef(name = "literal", type = JAXBElement.class, required = false), 
    @XmlElementRef(name = "emphasis", type = Emphasis.class, required = false), 
    @XmlElementRef(name = "note", type = Note.class, required = false), 
    @XmlElementRef(name = "link", type = Link.class, required = false), 
    @XmlElementRef(name = "informaltable", type = Informaltable.class, required = false), 
    @XmlElementRef(name = "itemizedlist", type = Itemizedlist.class, required = false), 
    @XmlElementRef(name = "subscript", type = JAXBElement.class, required = false) 
}) 
@XmlMixed 
protected List<Object> content; 

/* comment deleted */ 

public List<Object> getContent() { 
    if (content == null) { 
     content = new ArrayList<Object>(); 
    } 
    return this.content; 
} 

} 

Mein Debugger zeigt, dass der Code korrekt den gesamten Baum auffüllt, aber wenn der Baum mit dem Einweiser gespeist wird, die Einweiser Drosseln.

Hier ist der Code, den den Einweiser nennt (in einem Try-Block):

 File outputfile = new File(pathandfile); 
     JAXBContext jaxbc = JAXBContext.newInstance(Descriptions.class); 
     Marshaller jaxbm = jaxbc.createMarshaller(); 

     jaxbm.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 

     jaxbm.marshal(des, outputfile); 
     jaxbm.marshal(des, System.out); 

Diese Variablen durch die anrufenden Methode geliefert werden:

  • pathandfile: der Pfad und Dateinamen der Ausgabedatei.
  • des: die komplett montiert Java Baum

Was bin ich?

Antwort

1

ArrayList Klasse hat keine JAXB Anmerkungen darauf. Aus diesem Grund kann JAXB solche Java-Objekte nicht analysieren und löst diesen Fehler aus. Diese article erklärt im Detail.

Kurz gesagt, können Sie Wrapper-Klasse erstellen, die Ihre Liste

@XmlRootElement(name = "descriptions") 
@XmlAccessorType (XmlAccessType.FIELD) 
public class Descriptions 
{ 
@XmlElement(name = "description") 
private List<Description> descriptions = null; 

public List<Description> getDescriptions() { 
    return descriptions; 
} 

public void setDescriptions(List<Description> descriptions) { 
    this.descriptions = descriptions; 
} 
} 

Sie können Setup die Beschreibung hält, z.B.

Descriptions descriptions = new Descriptions(); 

Description description = new Description(); 
// set properties here 

descriptions.setDescriptions(new ArrayList<Description>()); 

Zuletzt;

JAXBContext context = JAXBContext.newInstance(Descriptions.class); 
Marshaller marshaller = context.createMarshaller(); 

marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
marshaller.marshal(descriptions, System.out); 

Dies ist nur ein Beispiel, Sie müssen möglicherweise entsprechend Ihrem Anwendungsfall ändern.

+0

Der referenzierte Artikel identifiziert das Problem und bietet eine gute Lösung, aber Link-Only-Antworten sind spröde, weil Links immer schal zu werden scheinen (ich musste meine eigenen Link-Only-Antworten aus dem gleichen Grund aktualisieren). Ihre Antwort wird erheblich verbessert, wenn Sie die Lösung angeben, ein einfaches Codebeispiel hinzufügen und vielleicht eine Beispielausgabe (wie im Artikel). Auf diese Weise wird es für immer gültig bleiben. –

+0

@SeanMickey Ich habe die Antwort aktualisiert. Danke – fabfas

+0

Danke für deine Hilfe, aber ich habe noch Fragen. Mein JAXB-Baum für meine Ausgabedatei enthält andere (nicht gemischte) Elemente, die Listen sind, und sie können problemlos analysiert werden, daher scheint der Kommentar zu ArrayList deaktiviert zu sein. Das Beispiel in der Verknüpfung, die Sie zur Verfügung gestellt haben, sieht genauso aus wie die anderen Klassen, die funktionieren, also nicht gemischte Typen. Das hilft nicht. Ich verstehe nicht, wo diese "Wrapper" -Klasse passt. Ich möchte nicht, dass es ein neues Element in meinem Ausgabe-XML erstellt, also was mache ich damit? Erstellen Sie ein Objekt, das den Inhalt darstellt, und fügen Sie es dann sowohl dem Wrapper als auch dem übergeordneten Element hinzu. –

Verwandte Themen