我面临的问题是如何将大量对象编码为一个XML文件,因此,我无法一步一步将完整列表编码。我有一个方法以块的形式返回这些对象,但是随后我使用JAXB封送了这些对象,封送器返回了,但这些对象不是根元素。正常情况下,您可以一步一步整理整个文档,这是可以的,但是如果我将JAXB_FRAGMENT属性设置为true,也会发生这种情况。

这是所需的XML输出:

<rootElem>
    <startDescription></startDescription>
    <repeatingElem></repeatingElem>
    <repeatingElem></repeatingElem>...
</rootElem>

因此,我假设我需要某种侦听器,该侦听器会动态加载下一个repeatingElements的下一部分,以将其馈送给编码,然后再编写rootElement的结束标记。但是该怎么做呢?到目前为止,我仅使用JAXB来编码小文件,而JAXB文档并未对该用例给出太多提示。

最佳答案

我知道这是一个老问题,但是我在搜索另一个类似问题的副本时遇到了它。

正如@skaffman所建议的那样,您想在启用JAXB_FRAGMENT并将对象包装在JAXBElement中的情况下进行封送。然后,您重复封送重复元素的每个单独实例。基本上听起来您想要这样的东西:

public class StreamingMarshal<T>
{
    private XMLStreamWriter xmlOut;
    private Marshaller marshaller;
    private final Class<T> type;

    public StreamingMarshal(Class<T> type) throws JAXBException
    {
        this.type = type;
        JAXBContext context = JAXBContext.newInstance(type);
        Marshaller m = context.createMarshaller();
        m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
    }

    public void open(String filename) throws XMLStreamException, IOException
    {
        xmlOut = XMLOutputFactory.newFactory().createXMLStreamWriter(new FileOutputStream(filename));
        xmlOut.writeStartDocument();
        xmlOut.writeStartElement("rootElement");
    }

    public void write(T t) throws JAXBException
    {
        JAXBElement<T> element = new JAXBElement<T>(QName.valueOf(type.getSimpleName()), type, t);
        marshaller.marshal(element, xmlOut);
    }

    public void close() throws XMLStreamException
    {
        xmlOut.writeEndDocument();
        xmlOut.close();
    }
}

07-24 22:26