2017-06-29 3 views
1

これはJava JAXBの質問です。私は、XMLから混合コンテンツ要素を読み込むと、別のXMLファイルに出力し、それをしようとしていますが、私は私のXML出力にJavaクラスからマーシャリングしようとすると、私は次のエラーを取得する:混在コンテンツノードをどのようにマーシャリングするのですか?私は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.]

問題の原因となるXML要素は、スキーマに次のようになります。

<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"

は、私がEclipseにスキーマをロードし、は私のJavaクラスを取得するには> JAXBクラス>を右クリックして生成します。私はこの出力を変更しません。

@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; 
} 

} 

私のデバッガは、コードが正しくツリー全体を移入することを示しているが、そのツリーはマーシャラーに供給しますと、マーシャラーはチョーク:このクラスは、このように見てしまいます。

は、ここで(tryブロック内)マーシャラーを呼び出すコードです:

 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); 

これらの変数は、呼び出しメソッドによって提供されています。

  • pathandfile:のパス名およびファイル名出力ファイル。
  • :完全に組み立てられたJavaツリー

私は何をしないのですか?

答えて

1

ArrayListクラスには、JAXBアノテーションはありません。このため、JAXBはそのようなJavaオブジェクトを解析できず、このエラーが発生します。このarticleが詳細に説明しています。要するに

は、あなたのリストを保持するラッパークラスを作成することができます

@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; 
} 
} 

あなたのセットアップの説明をすることができ、例えば

Descriptions descriptions = new Descriptions(); 

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

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

最後に、

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

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

これは一例であり、あなたはあなたのユースケースに応じて変更する必要があります。

+0

リンク先の記事は問題を特定し、良い解決策を提供しますが、リンクが常に古くなっているようです(同じ理由でリンク専用の回答を更新する必要があったため)。あなたが解決策を述べ、簡単なコードサンプル、そしておそらくサンプル出力を含むならば、あなたの答えは大幅に改善されます(記事のように)。そうすれば、永遠に有効になります。 –

+0

@SeanMickey答えを更新しました。ありがとう – fabfas

+0

あなたの助けをありがとうが、私はまだ質問があります。 私の出力ファイル用の私のJAXBツリーには、リストである他の(混合型でない)要素が含まれていますが、ArrayListに関するコメントが消えているようです。 あなたが提供したリンクの例は、動作する他のクラス、つまり非混合型と同じように見えます。それは助けにはならない。 この「ラッパー」クラスが適合する場所はわかりません。出力XMLに新しい要素を作成したくないので、どうしたらいいですか?コンテンツを表すオブジェクトを作成し、それをラッパーとその親の両方に追加しますか? –

関連する問題