11

When I marshal an XML with this attribute

marshal.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
marshal.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

it will generate an empty line break at the very top

//Generate empty line break here    
<XX>
    <YY>
        <PDF>pdf name</PDF>
        <ZIP>zip name</ZIP>
        <RECEIVED_DT>received date time</RECEIVED_DT>
    </YY>
</XX>

I think the reason is because marshal.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);, which remove <?xml version="1.0" encoding="UTF-8" standalone="yes"?>, leave the output xml a line break in the beginning. Is there a way to fix this? I use JAXB come with JDK 6, does Moxy suffer from this problem?

Thang Pham
  • 38,125
  • 75
  • 201
  • 285
  • 1
    Well. I tried Moxy JAXB, and MOxy does not suffer this problem. Glad Moxy is now a standard provider for Glassfish3.1.2. When will Moxy become standard JAXB provider for JDK? – Thang Pham Mar 06 '12 at 20:12
  • EclipseLink JAXB (MOXy) passes the same compliance tests as the reference implementation does, so can use us without worry (http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html). As you point out, MOXy is included in GlassFish 3.1.2 (http://blog.bdoughan.com/2012/02/glassfish-312-is-full-of-moxy.html). We are also the default JAXB implementation in WebLogic 12c (http://blog.bdoughan.com/2011/12/eclipselink-moxy-is-jaxb-provider-in.html). – bdoughan Mar 07 '12 at 14:29
  • I think JDK 7 must have fixed this because I don't seem to have this problem. – Adam Gent Feb 02 '15 at 18:06

3 Answers3

2

As you point out EclipseLink JAXB (MOXy) does not have this problem so you could use that (I'm the MOXy lead):

Option #1

One option would be to use a java.io.FilterWriter or java.io.FilterOutputStream and customize it to ignore the leading new line.

Option #2

Another option would be to marshal to StAX, and use a StAX implementation that supports formatting the output. I haven't tried this myself but the answer linked below suggests using com.sun.xml.txw2.output.IndentingXMLStreamWriter.

Community
  • 1
  • 1
bdoughan
  • 147,609
  • 23
  • 300
  • 400
1

Inspired by first option of bdoughan's comment in this post, I've written a custom writer to remove blank line in xml file like the following ways:

public class XmlWriter extends FileWriter {

    public XmlWriter(File file) throws IOException {
        super(file);
    }

    public void write(String str) throws IOException {
        if(org.apache.commons.lang3.StringUtils.isNotBlank(str)) {
            super.write(str);
        }
    }
}

To check empty line, I've used org.apache.commons.lang3.StringUtils.isNotBlank() method, you can use your own custom condition.

Then use this writer to marshal method like the following way in Java 8.

// skip other code
File file = new File("test.xml");
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
try (FileWriter writer = new XmlWriter(file)) {
    marshaller.marshal(object, writer);
}

It'll remove <?xml version="1.0" encoding="UTF-8" standalone="yes"?> tag, also will not print blank line.

arifng
  • 726
  • 1
  • 12
  • 22
0

Since I was marshalling to a File object, I decided to remove this line afterwards:

public static void removeEmptyLines(File file) throws IOException {
    long fileTimestamp = file.lastModified();
    List<String> lines = Files.readAllLines(file.toPath());
    try (Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8))) {
        for (String line : lines) {
            if (!line.trim().isEmpty()) {
                writer.write(line + "\n");
            }
        }
    }
    file.setLastModified(fileTimestamp);
}
Anthony
  • 1,245
  • 1
  • 16
  • 15