简体   繁体   中英

JAXB append a xml into a object to be marshaled

I'd like to append a marshaled object (xml code) into another object to be marshaled.

@XmlRootElement
object Child{ 
    ...
}

@XmlRootElement
object Parent{
    @XmlElement
    object Any;
}

Marshaling Child:

<child xmlns="namespaceOfChild.org">
    <...>
    <...>
<\child>

I'd like to set the xml above on Parent.Any to result the code bellow when Parent is marshaled.

<parent xmlns="namespaceOfParent.org">
    <any>
        <child xmlns="namespaceOfChild.org">
            <...>
            <...>
        <\child>
    <\any>
<\parent>

Note that the namespaces, and other attributes of child, must follow the child tag as the code above. I got success when I set the object Child itself on Parent.Any, but the attributes of Child appears like attributes of Parent.

I got it! I could save the internal element, Child , in a Document (org.w3c.dom.Document) and used the function to marshal the Child that returned document.getDocumentElement() to a Node (org.w3c.dom.Node). Then I used this Node to set the object in Parent.Any and after I can marshal the Parent .

Function to marshal Child:

private static Node marshal(Object obj) throws JAXBException {
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setNamespaceAware(true);
    Document doc = null;
    try {
        DocumentBuilder db = dbf.newDocumentBuilder();
        doc = db.newDocument();
    } catch (ParserConfigurationException ex) {
        throw new JAXBException(ex);
    }

    context = JAXBContext.newInstance("org.openarchives.oai._2_0.oai_dc");
    Marshaller m = context.createMarshaller();
    m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
    m.marshal(obj, doc);
    return  doc.getDocumentElement();
}

Function to marshal the Parent:

private static void marshal(Object obj, OutputStream stream) throws JAXBException {
    context  = JAXBContext.newInstance("org.openarchives.oai._2");
    Marshaller m = context.createMarshaller();
    m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
    m.marshal(obj, stream);
}

When I marshal the Parent, the attributes of Child are inside of <child> and the attributes of Parent are inside of <parent> .

Good answer, it guided me to the final solution in my environment.

For the one of you, that are trying to do this with JAX-RS and JERSEY JAXB implementation, that are the final steps I had to do.

Let say, we have parent class called metadataType, with a child of XML type "any" and we want to assign a class called Record

This is the "setting" of the object i did when i am creating the object

Document doc = null;
    try {
        JAXBContext jaxbContext = JAXBContext.newInstance(OAIPMHtype.class,Record.class,RDF.class);
        Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
        jaxbMarshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, "http://www.europeana.eu/schemas/ese/ " +
                "http://www.europeana.eu/schemas/ese/ESE-V3.4.xsd");
        jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);

        try {
            DocumentBuilder db = dbf.newDocumentBuilder();
            doc = db.newDocument();

        } catch (ParserConfigurationException ex) {
            throw new JAXBException(ex);
        }
        jaxbMarshaller.marshal(record, doc);
    } catch (JAXBException e) {
        throw new JAXBException(e);
    }
        metadataType.setAny(doc.getDocumentElement());

And in the class Record I had to add @XMLRootElement , like:

@XmlRootElement(name = "record",namespace = "http://www.europeana.eu/schemas/ese/")

Then, if you let Jersey Marshall automatically or not this object it will generate

<root xmlns="http://rootschema"><metadata><ese:record xmlns:ese="http://www.europeana.eu/schemas/ese/" schemaLocation="http://www.europeana.eu/schemas/ese/ http://www.europeana.eu/schemas/ese/ESE-V3.4.xsd"> <metadata> </root>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM