Artem
Artem

Reputation: 505

Remove empty XML tags in jaxb marshalling

How can I avoid empty tags with jaxb marshaller?

final Marshaller marshaller = JAXBContext.newInstance(content.getClass()).createMarshaller();

final ByteArrayOutputStream stream = new ByteArrayOutputStream();
final XMLStreamWriter streamWriter = XMLOutputFactory.newInstance().createXMLStreamWriter(stream);

final CapitalizedXMLStreamWriter xmlStreamWriter = new CapitalizedXMLStreamWriter(streamWriter);

marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, schemaLocation);
marshaller.setAdapter(new NullAdapter());
marshaller.marshal(content, xmlStreamWriter);

xmlStreamWriter.flush();
xmlStreamWriter.close();

final String xml = new String(stream.toByteArray());

CapitalizedXMLStreamWriter is my writer that extends StreamWriterDelegate. It just overrides writeStartElement as this.mDelegate.writeStartElement(arg0, capitalize(arg1));

And I use annotations in package-info for namespaces.

I tried to use marshaller.setAdapter() but nothing happends.

Upvotes: 3

Views: 6051

Answers (1)

Mubashar
Mubashar

Reputation: 12668

I couldn't find a global way to remove the empty tag completely (other than by not setting the property in pojo before serialisation) however if you like to convert all empty strings to nulls i.e. <tagA></tagA> to <tagA/> you can use XmlAdapter class as following;

Step 1 Extend XmlAdapter

package com.xyz.mylib;

import javax.xml.bind.annotation.adapters.XmlAdapter;

public class EmptyValueCleanerXmlAdapter extends XmlAdapter<String, String> {
    @Override
    public String unmarshal(String value) {
        return value;
    }

    @Override
    public String marshal(String value) {
        return (value != null && value.length() == 0) ? null : value;
    }
}

Step 2: Apply on pojo: There are you apply it different ways but one of the global way would be to create a package-info.java file as following (it would go into the package of whereever your pojo is)

@XmlJavaTypeAdapters({
    @XmlJavaTypeAdapter(EmptyValueCleanerXmlAdapter.class)
})
package com.myapp.pojos;

import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters;
import com.xyz.mylib.EmptyValueCleanerXmlAdapter;

Edit: Alternative solution
I end up using regex on xml to strip away any empty tags. see below

// identifies empty tag i.e <tag1></tag> or <tag/>
// it also supports the possibilities of white spaces around or within the tag. however tags with whitespace as value will not match.
private static final String EMPTY_VALUED_TAG_REGEX = "\\s*<\\s*(\\w+)\\s*></\\s*\\1\\s*>|\\s*<\\s*\\w+\\s*/\\s*>";

Run the code on ideone

Upvotes: 3

Related Questions