【问题标题】:JAXB: Marshal output XML with indentation create empty line break on the first lineJAXB:带缩进的编组输出 XML 在第一行创建空换行符
【发布时间】:2012-03-24 08:04:44
【问题描述】:

当我用这个属性编组一个 XML 时

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

它会在最顶部生成一个空的换行符

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

我认为原因是因为marshal.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE); 删除了&lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&gt;,在输出xml 的开头留了一个换行符。有没有办法来解决这个问题?我使用的是 JDK 6 自带的 JAXB,Moxy 有这个问题吗?

【问题讨论】:

  • 好吧。我试过 Moxy JAXB,MOxy 没有这个问题。 Glad Moxy 现在是 Glassfish3.1.2 的标准提供者。 Moxy 何时会成为 JDK 的标准 JAXB 提供者?
  • EclipseLink JAXB (MOXy) 通过了与参考实现相同的合规性测试,因此可以放心使用我们 (blog.bdoughan.com/2011/05/…)。正如您所指出的,MOXy 包含在 GlassFish 3.1.2 (blog.bdoughan.com/2012/02/glassfish-312-is-full-of-moxy.html) 中。我们也是 WebLogic 12c (blog.bdoughan.com/2011/12/…) 中默认的 JAXB 实现。
  • 我认为 JDK 7 一定已经解决了这个问题,因为我似乎没有这个问题。

标签: java jaxb moxy


【解决方案1】:

正如你所指出的,EclipseLink JAXB (MOXy) 没有这个问题,所以你可以使用它(我是 MOXy 领导):

选项#1

一种选择是使用java.io.FilterWriterjava.io.FilterOutputStream 并对其进行自定义以忽略前导新行。

选项 #2

另一种选择是编组到 StAX,并使用支持格式化输出的 StAX 实现。我自己没有尝试过,但下面链接的答案建议使用com.sun.xml.txw2.output.IndentingXMLStreamWriter

【讨论】:

    【解决方案2】:

    受本文中bdoughan's comment 的第一个选项的启发,我编写了一个自定义编写器来删除 xml 文件中的空白行,如下所示:

    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);
            }
        }
    }
    

    检查空行,我使用org.apache.commons.lang3.StringUtils.isNotBlank()方法,你可以使用你自己的自定义条件。

    然后在 Java 8 中使用这个 writer 来编组方法,如下所示。

    // 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);
    }
    

    它会删除&lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&gt;标签,也不会打印空行。

    【讨论】:

      【解决方案3】:

      因为我正在编组到一个 File 对象,所以我决定在之后删除这一行:

      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);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多