如何编组混合内容节点?我得到了一个Marshal.Exception

时间:2017-06-29 10:05:51

标签: java jaxb marshalling mixed-content

这是一个Java JAXB问题。我正在读取XML中的混合内容元素并尝试将其输出到另一个XML文件中,但是当我尝试从Java类编组到我的XML输出时,我收到以下错误:

  

[com.sun.istack.internal.SAXException2:class java.util.ArrayList nor   任何超级类都是这种情况所知的。   javax.xml.bind.JAXBException:类java.util.ArrayList也不是任何一个   超类在这种情况下是已知的。]

导致问题的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>
  

注意:mixed =“true”

我将架构加载到Eclipse中并使用右键单击&gt;生成&gt; JAXB Classes 来获取我的Java类。我不修改此输出。这堂课看起来像这样:

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

}

我的调试器显示代码正确填充了整个树,但是当该树被送到编组器时,编组器会窒息。

这是调用marshaller的代码(在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 :输出文件的路径名和文件名。
  • des :完全组装的Java树

我错过了什么?

1 个答案:

答案 0 :(得分: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); 

这只是一个例子,您可能需要根据您的使用情况进行更改。