Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JAXB Fragmented Marshalling

Tags:

java

xml

jaxb

I'm having some trouble successfully marshalling using the Marshaller.JAXB_FRAGMENT property. Here's a simple version of the XML i'm trying to output.

<Import>
    <WorkSets>
        <WorkSet>
            <Work>
            <Work>
            ...
            ..
            ...
        </WorkSet>
        <WorkSet>
            <Work>
            <Work>
            ...
        </WorkSet>
    <WorkSets>
<Import>

The <Import> and <WorkSets> elements are essentially just container elements that enclose a large number of <WorkSet> & <Work> elements. I'm currently trying to marshall at the <WorkSet>.

  1. Is it possible to initially marshal the <Import> and <WorkSets> elements and then from then on marshal at the <WorkSet> element and have the output be enclosed in the <Import><WorkSets> tags?
  2. When I'm marshaling at the WorkSet level it attaches the xmlns='http://namespace.com' attribute to the WorkSet tag, is there a way to marshal without the namespace attribute being attached to Workset?
like image 213
TyC Avatar asked Feb 15 '12 14:02

TyC


People also ask

What is JAXB fragment?

fragment – It determines whether or not document level events will be generated by the Marshaller. Value can be true or false .

How does JAXB marshalling work?

In JAXB, marshalling involves parsing an XML content object tree and writing out an XML document that is an accurate representation of the original XML document, and is valid with respect the source schema. JAXB can marshal XML data to XML documents, SAX content handlers, and DOM nodes.

What is Jaxb_formatted_output?

JAXB_FORMATTED_OUTPUT. The name of the property used to specify whether or not the marshalled XML data is formatted with linefeeds and indentation. static String.

What is a Marshaller in Java?

The Marshaller class is responsible for governing the process of serializing Java content trees back into XML data.


1 Answers

Basically, it sounds like rather than constructing a full object tree with the container objects, you want to be able to stream a collection of WorkSet instances to marshal using JAXB.

The approach I would take is to use an XMLStreamWriter and marshal the WorkSet objects by wrapping them in a JAXBElement. I don't have tested sample code close at hand, so here's the rough code snippet that should put you on the write track:

FileOutputStream fos = new FileOutputStream("foo.xml");
XMLStreamWriter writer = XMLOutputFactory.newFactory().createXMLStreamWriter(fos);

writer.writeStartDocument();
writer.writeStartElement("Import");
writer.writeStartElement("WorkSets");

JAXBContext context = JAXBContext.newInstance(WorkSet.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE); 
for (WorkSet instance : instances)
{
    JAXBElement<WorkSet> element = new JAXBElement<WorkSet>(QName.valueOf("WorkSet"), WorkSet.class, instance);
    m.marshal(element, writer);
}

writer.writeEndDocument(); // this will close any open tags
writer.close();

Note: The above is completely untested and may be messing something up in the wrapping part to write each instance of WorkSet. You need to wrap the WorkSet instances because they will not be annotated with @XmlRootElement and JAXB will otherwise refuse to marshal the objects.

like image 135
Ophidian Avatar answered Sep 23 '22 07:09

Ophidian