如何封送混合内容节点?我得到一个Marshal.Exception

问题描述:

这是一个Java JAXB问题。我读的XML格式的混合内容元素,并试图在另一XML文件输出,但是当我试图从Java类编组到我的XML输出,我得到以下错误:如何封送混合内容节点?我得到一个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和使用右键单击>生成> JAXB类让我的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; 
} 

} 

我的调试器显示代码正确填充整个树,但是当树被送入编组,编组扼流圈。

下面是调用编组(一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树

我缺少什么?

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中创建一个新元素,那么我该怎么处理它?创建一个表示内容的对象,然后将其添加到包装器及其父级? –