Как маршалировать объект JAXB для org.w3c.dom.Document?

Это дает мне объект Document с верхним уровнем node без дочерних узлов:

public static Document getDocument(Object jaxb)
{
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    //dbf.setNamespaceAware(true);
    Document doc = dbf.newDocumentBuilder().newDocument(); 

    JAXBContext context = JAXBContext.newInstance(jaxb.getClass());
    context.createMarshaller().marshal(jaxb, doc);

    return doc;
}

Это обходной путь, который кажется еще более неэффективным, поскольку он преобразуется в String, а затем в Document.

public static Document getDocument(Object jaxb)
{                           
    StringWriter writer = new StringWriter();       
    JAXBContext context = JAXBContext.newInstance(jaxb.getClass());
    context.createMarshaller().marshal(jaxb, writer);

    return DocumentBuilderFactory.newInstance().newDocumentBuilder().
parse(new InputSource(new StringReader(writer.toString()));
}

Можно ли выполнить то, что я пытаюсь выполнить?

Ответ 1

То, что вы делаете, должно работать. Вот пример:

Модель домена (Foo)

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Foo {

    private String bar;

    public String getBar() {
        return bar;
    }

    public void setBar(String bar) {
        this.bar = bar;
    }

}

Demo

import javax.xml.bind.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;

public class Demo {

    public static void main(String[] args) throws Exception {
        // Create the JAXBContext
        JAXBContext jc = JAXBContext.newInstance(Foo.class);

        // Create the Object
        Foo foo = new Foo();
        foo.setBar("Hello World");

        // Create the Document
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document document = db.newDocument();

        // Marshal the Object to a Document
        Marshaller marshaller = jc.createMarshaller();
        marshaller.marshal(foo, document);

        // Output the Document
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer t = tf.newTransformer();
        DOMSource source = new DOMSource(document);
        StreamResult result = new StreamResult(System.out);
        t.transform(source, result);
    }

}

Выход

<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>Hello World</bar></foo>

Ответ 2

попробуйте это

    DOMResult res = new DOMResult();
    JAXBContext context = JAXBContext.newInstance(obj.getClass());
    context.createMarshaller().marshal(obj, res);
    Document doc = (Document) res.getNode();