本文翻译自:How to pretty print XML from Java?

I have a Java String that contains XML, with no line feeds or indentations. 我有一个包含XML的Java字符串,没有换行符或缩进。 I would like to turn it into a String with nicely formatted XML. 我想把它变成一个格式很好的XML的字符串。 How do I do this? 我该怎么做呢?

String unformattedXml = "<tag><nested>hello</nested></tag>";
String formattedXml = new [UnknownClass]().format(unformattedXml);

Note: My input is a String . 注意:我的输入是一个字符串 。 My output is a String . 我的输出是一个字符串 。

(Basic) mock result: (基本)模拟结果:

<?xml version="1.0" encoding="UTF-8"?>
<root><tag><nested>hello</nested></tag>
</root>

#1楼

参考:https://stackoom.com/question/aBA/如何从Java中打印XML


#2楼

I have found that in Java 1.6.0_32 the normal method to pretty print an XML string (using a Transformer with a null or identity xslt) does not behave as I would like if tags are merely separated by whitespace, as opposed to having no separating text. 我发现在Java 1.6.0_32中,相当于打印XML 字符串 (使用带有null或身份xslt的Transformer)的常规方法,如果标签仅由空格分隔,则表现不像我想要的那样,而不是没有分隔文本。 I tried using <xsl:strip-space elements="*"/> in my template to no avail. 我尝试在我的模板中使用<xsl:strip-space elements="*"/>无效。 The simplest solution I found was to strip the space the way I wanted using a SAXSource and XML filter. 我发现最简单的解决方案是使用SAXSource和XML过滤器以我想要的方式剥离空间。 Since my solution was for logging I also extended this to work with incomplete XML fragments. 由于我的解决方案是用于日志记录,我还将其扩展为使用不完整的XML片段。 Note the normal method seems to work fine if you use a DOMSource but I did not want to use this because of the incompleteness and memory overhead. 请注意,如果使用DOMSource,正常方法似乎工作正常,但由于不完整性和内存开销,我不想使用它。

public static class WhitespaceIgnoreFilter extends XMLFilterImpl
{@Overridepublic void ignorableWhitespace(char[] arg0,int arg1,int arg2) throws SAXException{//Ignore it then...}@Overridepublic void characters( char[] ch,int start,int length) throws SAXException{if (!new String(ch, start, length).trim().equals("")) super.characters(ch, start, length); }
}public static String prettyXML(String logMsg, boolean allowBadlyFormedFragments) throws SAXException, IOException, TransformerException{TransformerFactory transFactory = TransformerFactory.newInstance();transFactory.setAttribute("indent-number", new Integer(2));Transformer transformer = transFactory.newTransformer();transformer.setOutputProperty(OutputKeys.INDENT, "yes");transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");StringWriter out = new StringWriter();XMLReader masterParser = SAXHelper.getSAXParser(true);XMLFilter parser = new WhitespaceIgnoreFilter();parser.setParent(masterParser);if(allowBadlyFormedFragments){transformer.setErrorListener(new ErrorListener(){@Overridepublic void warning(TransformerException exception) throws TransformerException{}@Overridepublic void fatalError(TransformerException exception) throws TransformerException{}@Overridepublic void error(TransformerException exception) throws TransformerException{}});}try{transformer.transform(new SAXSource(parser, new InputSource(new StringReader(logMsg))), new StreamResult(out));}catch (TransformerException e){if(e.getCause() != null && e.getCause() instanceof SAXParseException){if(!allowBadlyFormedFragments || !"XML document structures must start and end within the same entity.".equals(e.getCause().getMessage())){throw e;}}else{throw e;}}out.flush();return out.toString();}

#3楼

Now it's 2012 and Java can do more than it used to with XML, I'd like to add an alternative to my accepted answer. 现在是2012年,Java可以比以前用XML更多,我想为我接受的答案添加一个替代方案。 This has no dependencies outside of Java 6. 这与Java 6之外没有依赖关系。

import org.w3c.dom.Node;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSSerializer;
import org.xml.sax.InputSource;import javax.xml.parsers.DocumentBuilderFactory;
import java.io.StringReader;/*** Pretty-prints xml, supplied as a string.* <p/>* eg.* <code>* String formattedXml = new XmlFormatter().format("<tag><nested>hello</nested></tag>");* </code>*/
public class XmlFormatter {public String format(String xml) {try {final InputSource src = new InputSource(new StringReader(xml));final Node document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(src).getDocumentElement();final Boolean keepDeclaration = Boolean.valueOf(xml.startsWith("<?xml"));//May need this: System.setProperty(DOMImplementationRegistry.PROPERTY,"com.sun.org.apache.xerces.internal.dom.DOMImplementationSourceImpl");final DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();final DOMImplementationLS impl = (DOMImplementationLS) registry.getDOMImplementation("LS");final LSSerializer writer = impl.createLSSerializer();writer.getDomConfig().setParameter("format-pretty-print", Boolean.TRUE); // Set this to true if the output needs to be beautified.writer.getDomConfig().setParameter("xml-declaration", keepDeclaration); // Set this to true if the declaration is needed to be outputted.return writer.writeToString(document);} catch (Exception e) {throw new RuntimeException(e);}}public static void main(String[] args) {String unformattedXml ="<?xml version=\"1.0\" encoding=\"UTF-8\"?><QueryMessage\n" +"        xmlns=\"http://www.SDMX.org/resources/SDMXML/schemas/v2_0/message\"\n" +"        xmlns:query=\"http://www.SDMX.org/resources/SDMXML/schemas/v2_0/query\">\n" +"    <Query>\n" +"        <query:CategorySchemeWhere>\n" +"   \t\t\t\t\t         <query:AgencyID>ECB\n\n\n\n</query:AgencyID>\n" +"        </query:CategorySchemeWhere>\n" +"    </Query>\n\n\n\n\n" +"</QueryMessage>";System.out.println(new XmlFormatter().format(unformattedXml));}
}

#4楼

a simpler solution based on this answer : 基于这个答案的更简单的解决方案 :

public static String prettyFormat(String input, int indent) {try {Source xmlInput = new StreamSource(new StringReader(input));StringWriter stringWriter = new StringWriter();StreamResult xmlOutput = new StreamResult(stringWriter);TransformerFactory transformerFactory = TransformerFactory.newInstance();transformerFactory.setAttribute("indent-number", indent);Transformer transformer = transformerFactory.newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes");transformer.transform(xmlInput, xmlOutput);return xmlOutput.getWriter().toString();} catch (Exception e) {throw new RuntimeException(e); // simple exception handling, please review it}
}public static String prettyFormat(String input) {return prettyFormat(input, 2);
}

testcase: 测试用例:

prettyFormat("<root><child>aaa</child><child/></root>");

returns: 收益:

<?xml version="1.0" encoding="UTF-8"?>
<root><child>aaa</child><child/>
</root>

#5楼

Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
//initialize StreamResult with File object to save to file
StreamResult result = new StreamResult(new StringWriter());
DOMSource source = new DOMSource(doc);
transformer.transform(source, result);
String xmlString = result.getWriter().toString();
System.out.println(xmlString);

Note: Results may vary depending on the Java version. 注意:结果可能因Java版本而异。 Search for workarounds specific to your platform. 搜索特定于您的平台的变通方法。


#6楼

Since you are starting with a String , you need to covert to a DOM object (eg Node ) before you can use the Transformer . 由于您是以String开头的,因此在使用Transformer之前,需要转换为DOM对象(例如Node )。 However, if you know your XML string is valid, and you don't want to incur the memory overhead of parsing a string into a DOM, then running a transform over the DOM to get a string back - you could just do some old fashioned character by character parsing. 但是,如果您知道您的XML字符串是有效的,并且您不希望产生将字符串解析为DOM的内存开销,那么在DOM上运行转换以获取字符串 - 您可以只做一些旧的字符解析。 Insert a newline and spaces after every </...> characters, keep and indent counter (to determine the number of spaces) that you increment for every <...> and decrement for every </...> you see. 在每个</...>字符后面插入换行符和空格,保留和缩进计数器(以确定空格数),为每个<...>递增,并为每个</...>减少。

Disclaimer - I did a cut/paste/text edit of the functions below, so they may not compile as is. 免责声明 - 我对下面的函数进行了剪切/粘贴/文本编辑,因此它们可能无法按原样编译。

public static final Element createDOM(String strXML) throws ParserConfigurationException, SAXException, IOException {DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();dbf.setValidating(true);DocumentBuilder db = dbf.newDocumentBuilder();InputSource sourceXML = new InputSource(new StringReader(strXML))Document xmlDoc = db.parse(sourceXML);Element e = xmlDoc.getDocumentElement();e.normalize();return e;
}public static final void prettyPrint(Node xml, OutputStream out)throws TransformerConfigurationException, TransformerFactoryConfigurationError, TransformerException {Transformer tf = TransformerFactory.newInstance().newTransformer();tf.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8");tf.setOutputProperty(OutputKeys.INDENT, "yes");tf.transform(new DOMSource(xml), new StreamResult(out));
}

如何从Java中打印XML?相关推荐

  1. matlab分析xml文件_如何在Java中读取XML文件(DOM分析器)

    matlab分析xml文件 Today we will learn how to read the XML file in Java. We will also learn how to parse ...

  2. Java中操作Xml使用备忘

    List item 文章目录 Java中操作Xml使用备忘 1. Hutool中XmlUtil的使用简介 2. Hutool中XmlUtil快速读取Xml字符串某个节点值 [简单取值时,推荐使用] 2 ...

  3. Java 中的 XML:Java 文档模型的用法

    Java 中的 XML:Java 文档模型的用法 英文原文 内容: 代码对比 DOM JDOM dom4j Electric XML XPP 结束语 下一次... 参考资料 关于作者 对本文的评价 相 ...

  4. java中拼写xml

    本文为博主原创,未经博主允许,不得转载: xml具有强大的功能,在很多地方都会用的到.比如在通信的时候,通过xml进行消息的发送和交互. 在项目中有很多拼写xml的地方,进行一个简单的总结. 先举例如 ...

  5. 宣布EAXY:使Java中的XML更容易

    Java中的XML库是一个雷区. 操作和读取XML所需的代码量令人震惊,使用不同的库遇到类路径问题的风险很大,并且对名称空间的处理带来许多混乱和错误. 最糟糕的是,情况似乎并没有改善. 一位同事让我意 ...

  6. 宣布EAXY:在Java中简化XML

    Java中的XML库是一个雷区. 操作和读取XML所需的代码量令人震惊,使用不同的库遇到类路径问题的风险很大,并且命名空间的处理带来了很多混乱和错误. 最糟糕的是,情况似乎并没有改善. 一位同事让我意 ...

  7. matlab分析xml文件_修改Java中的XML文件(DOM分析器)

    matlab分析xml文件 We can modify XML file in Java using DOM parser. We can add elements, remove elements, ...

  8. xstream xml模板_XStream – XStreamely使用Java中的XML数据的简便方法

    xstream xml模板 有时候,我们不得不处理XML数据. 而且大多数时候,这不是我们一生中最快乐的一天. 甚至有一个术语" XML地狱"描述了程序员必须处理许多难以理解的XM ...

  9. XStream – XStreamely使用Java中的XML数据的简便方法

    有时候,我们不得不处理XML数据. 而且大多数时候,这不是我们一生中最快乐的一天. 甚至有一个术语" XML地狱"描述了程序员必须处理许多难以理解的XML配置文件时的情况. 但是, ...

最新文章

  1. Binary Tree Preorder Traversal
  2. 剑指offer 算法 (抽象建模能力)
  3. java文本区显示在右边_怎么让文本区从右边开始显示文本
  4. 《Delphi XE6 android 编程入门教程》推荐
  5. 【数字逻辑 Verilog】全面剖析数据选择器——从基础到拓展,从理论到设计的实现,从表面到本质
  6. 处理器管理与进程调度
  7. 1分钟教你破解风行电视禁止安装应用!
  8. Linux系统版本介绍
  9. 青云决最新服务器,青云决合区表
  10. import xx fromxx 的含义
  11. springboot框架下的实时消息推送
  12. esp32 micropython 控制ws2812 RGB灯带
  13. 2022年3月份合肥教师考编报名(报名数学学科)
  14. TCP/IP协议栈 头部参数
  15. Sers微服务快速入门-00.目录
  16. 资产、负债及所有者权益类帐户
  17. [SRM] 10 CCZ的诗
  18. 望帝春心托杜鹃 中望帝的由来~
  19. 关于相机的一些参数计算(靶面、视野等)
  20. 观点:2009年协同办公软件市场谁称王?

热门文章

  1. 深圳腾讯内部Jetpack宝典意外流出!极致经典,堪称Android架构组件的天花板
  2. 【C++】修改const变量的值
  3. 使用Scroller实现弹性滑动
  4. Android之了解ThreadLocal
  5. 【Android基础】动画
  6. Flutter开发之Debug调试(十)
  7. python大数据搜索_python语言-用 Python 实现一个大数据搜索引擎
  8. 【转载】flash时间轴中变量的作用域
  9. 2019.03.28 bzoj3594: [Scoi2014]方伯伯的玉米田(二维bit优化dp)
  10. 对学校公开课信息网站一次渗透测试