漂亮地打印XML文件

3

原始问题

我想在没有任何外部库的情况下对XML文件进行漂亮的打印,但是无法让Java做我想要的事情... 这是我的代码(我添加了来自类似问题的任何解决方案!):

TransformerFactory tfactory = TransformerFactory.newInstance();
tfactory.setAttribute("indent-number", 4);
Transformer transformer = tfactory.newTransformer();
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
transformer.setOutputProperty(OutputKeys.MEDIA_TYPE, "text/xml");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
transformer.setOutputProperty("{http://xml.apache.org/xalan}indent-amount", "4");
transformer.setOutputProperty(OutputPropertiesFactory.S_KEY_INDENT_AMOUNT, "4");
File file = new File("C:\\text.xml");
DOMSource source = new DOMSource(DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file));
transformer.transform(source, new StreamResult(file));

有一个像这样的输入文件:

<?xml version="1.0" encoding="UTF-8" standalone="no"?><root><test><item0>a</item0><item1>b</item1></test></root>

我收到的输出看起来像这样:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<root>

<test>
<item0>a</item0>
<item1>b</item1>
    </test>
</root>

我不明白的是为什么在<root>后面会有一个空行,在</test>之前还有一次缩进,而其他地方却没有。在这个新文件上运行代码并没有改变任何东西!

我希望我的输出文件看起来像这样:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<root>
    <test>
        <item0>a</item0>
        <item1>b</item1>
     </test>
 </root>

更新

我已经从我的代码中删除了一些明显没有起到任何作用的行:

TransformerFactory tfactory = TransformerFactory.newInstance();
tfactory.setAttribute("indent-number", 4);
Transformer transformer = tfactory.newTransformer();
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
transformer.setOutputProperty("{http://xml.apache.org/xalan}indent-amount", "4");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
File file = new File("C:\\text.xml");
DOMSource source = new DOMSource(DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file));
transformer.transform(source, new StreamResult(file));

现在,从最初问题中的单行文件创建了一个漂亮的格式化文件,这部分问题已经解决了!我不知道具体问题是什么,但是无论如何,现在可以正常工作^^

但是,我的程序还会读取和写入一些旧文件,这些文件看起来有点像这样:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<root>
<test>
<item0>a</item0>
<item1>b</item1>
</test>
</root>

每个节点之后都有一个换行符,但没有缩进。我的代码保留了文件的原样... 我该如何更正?


当您运行代码时,tfactory的类是什么?您使用的JDK是什么? - wero
tfactory 的类型为 javax.xml.transform.TransformerFactory,我使用的是 1.8.0_66-b18(发布于2015年11月11日)。 - user2336377
tfactory的实现类是什么?即,当您打印System.out.println(tfactory.getClass())时。 - wero
com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl 类 - user2336377
奇怪的是,当我使用JDK 1.8.0_45(具有相同的转换器实现)运行您的代码时,我得到了一个漂亮的缩进输出。 - wero
2个回答

2
您标记了此为XSLT,如果应用以下XSLT样式表: XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xalan="http://xml.apache.org/xalan"
exclude-result-prefixes="xalan">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" xalan:indent-amount="4"/>

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

将您的XML输入添加到其中,结果将如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<root>
    <test>
        <item0>a</item0>
        <item1>b</item1>
    </test>
</root>

实时演示:http://xsltransform.net/ncdD7mg

请注意,项目被“漂亮地打印”如下:

<item0>a</item0>

不是您发布的那样,而是:
<item0>
    a
</item0>

这将代表XML内容有效载荷的更改。


请纠正问题中的固定内容不匹配。 - user2336377
@user2336377 您的问题没有得到解答吗? - michael.hor257k

0
为什么要费心写复杂、容易出错的Java代码,当你可以像这样简单地使用身份规则进行转换呢?
<xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output indent="yes"/>

  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

当应用此转换到提供的 XML 文档时

<?xml version="1.0" encoding="UTF-8" standalone="no"?><root><test><item0>a</item0><item1>b</item1></test></root>

产生一个漂亮,更重要的是统一(每个 XSLT 处理器)的输出:

<?xml version="1.0" encoding="utf-8"?>
<root>
   <test>
      <item0>a</item0>
      <item1>b</item1>
   </test>
</root>

当使用Xalan处理器(如OP显然所做)时,这不会是结果-请参见:http://xsltransform.net/ncdD7mg/1 - michael.hor257k

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接