Java中如何使用JAXB Marshaller自定义XML输出格式?
解决方案
下面提供两种可直接落地的实现方式:
方案1:JAXB原生配置+简单字符串后处理(最便捷)
首先关闭JAXB默认的格式化输出,再通过字符串替换调整换行规则,即可匹配你需要的输出格式:
import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import java.io.StringWriter; // 核心转换代码 public String marshallToCustomXml(Object javaObj) throws Exception { JAXBContext context = JAXBContext.newInstance(javaObj.getClass()); Marshaller marshaller = context.createMarshaller(); // 基础编码、 standalone 配置 marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); marshaller.setProperty(Marshaller.JAXB_STANDALONE, true); // 关闭默认格式化输出,避免生成多余缩进和换行 marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false); StringWriter writer = new StringWriter(); marshaller.marshal(javaObj, writer); String rawXml = writer.toString(); // 按业务需求自定义换行规则,可根据实际节点名调整 rawXml = rawXml.replaceAll("</time>", "</time>\n") .replaceAll("<details>", "<details>\n") .replaceAll("</employee>", "</employee>\n") .replaceAll("</details>", "\n</details>") .replaceAll("</xml>", "\n</xml>"); // 清理多余空行 return rawXml.replaceAll("\\n\\s+", "\n").trim(); }
方案2:自定义XMLStreamWriter控制输出(更严谨,无字符串匹配风险)
如果不想依赖字符串替换,可以自定义StreamWriter控制换行逻辑,完全精准控制输出格式:
import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamWriter; import java.io.StringWriter; public String marshallToCustomXml(Object javaObj) throws Exception { JAXBContext context = JAXBContext.newInstance(javaObj.getClass()); Marshaller marshaller = context.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); marshaller.setProperty(Marshaller.JAXB_STANDALONE, true); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false); StringWriter stringWriter = new StringWriter(); XMLOutputFactory factory = XMLOutputFactory.newInstance(); XMLStreamWriter originalWriter = factory.createXMLStreamWriter(stringWriter); // 自定义包装writer,仅在指定层级节点结束时插入换行 XMLStreamWriter customWriter = new XMLStreamWriterWrapper(originalWriter) { private int nodeDepth = 0; @Override public void writeStartElement(String localName) throws Exception { super.writeStartElement(localName); nodeDepth++; } @Override public void writeEndElement() throws Exception { super.writeEndElement(); nodeDepth--; // 根节点下一级节点(time、details)、details下的employee节点结束时插入换行 if (nodeDepth == 1 || nodeDepth == 2) { super.writeCharacters("\n"); } } }; marshaller.marshal(javaObj, customWriter); return stringWriter.toString(); }
注:XMLStreamWriterWrapper为XMLStreamWriter接口的默认代理实现类,仅需要默认实现所有接口方法,上述代码中重写节点起止方法自定义逻辑即可。
内容的提问来源于stack exchange,提问作者mugen032
相关产品推荐
相关产品推荐

