java生成xml文件的时候如何控制xml的缩进格式

使用java自带的xml api生成的xml文件,其格式都是没有缩进的,每个element都是顶到最前面,今天终于找到了比较好的处理方法,赶紧记下来.

使用Java标准的JAXP来输出可以使用:
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.transform(new DOMSource(document), new StreamResult(outputFile));
中间的红色代码是用于设置缩进的,比较遗憾的是JAXP只抽象出是否设置缩进(indent: yes|no),但并没有抽象出设置缩进量长度的常量(indent-number),所以默认的缩进量长度为0。如果有下面这样一个xml文档:<root><a><b>c</b></a></root>会被格式化为:
<root>
<a>
<b>c</b>
</a>
</root>
由于JAXP只是一个Java一个处理XML的框架,根据实现的不一样,可以传入实现特定的某个Key来设置缩进量。比如在Java 1.4下面,可以通过下面语句将缩进量设为2:
ransformer.setOutputProperty(
"{http://xml.apache.org/xslt}indent-amount", "2");

transformer.setOutputProperty(
 "{http://xml.apache.org/xalan}indent-amount", "2");
上面两句不同之处仅在于命名空间。

而在Java 1.5下面,情况就有些复杂了。Java 1.5集成了JXAP 1.3(Java 1.4集成的是JXAP 1.1,不同之处参见http://java.sun.com/j2se/1.5.0/docs/guide/xml/jaxp/JAXP-Compatibility_150.html),实现基于Xerces类库。由于内部实现上的Bug,导致了设置缩进的不同:
TransformerFactory tf = TransformerFactory.newInstance();
tf.setAttribute("indent-number", new Integer(2));
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.transform(new DOMSource(document), new StreamResult(new?BufferedWriter(new OutputStreamWriter(new FileOutputStream(outputFile)))));
注意红色代码的不同之处。第一句设置TransformerFactory的indent-number属性,在Java 1.4下面运行会抛出异常,因为其不支持该属性,而在Java 1.5中却只能通过该属性来设置缩进。后面标为红色的代码则是由于Sun实现上的Bug,只有通过StreamResult(Writer)构造函数生成才能正确设置缩进(通过OutputStream或者File生成的StreamResult是无法设置缩进的,其实现上会忽略任何非正式的属性,而仅仅采用rt.jar下面com\sun\org\apache\xml\internal\serializer\output_xml.properties中的配置。详细可以在com.sun.org.apache.xml.internal.serializer.ToStream类的setOutputStream方法中加断点进行分析)
?
如果忽略掉可移植性,确认绑定在Sun的JRE实现上面,则可以通过如下代码来更好的实现:
OutputFormat format = new OutputFormat(document);
format.setIndenting(true);
format.setIndent(2);
Writer output = new BufferedWriter( new FileWriter(outputFile) );
XMLSerializer serializer = new XMLSerializer(output, format);
serializer.serialize(document);
但是OutputFormat类和XMLSerializer类都是位于com.sun.org.apache.xml.internal.serialize包下。

如果应用对增加一个300K左右的jar包不敏感的话,我还是强烈推荐用dom4j来处理xml,其API设计的非常易用,写出来的代码比用JXAP写出来的代码漂亮多了,也容易维护,也不会出现上面那种两个Java版本不兼容的问题。

posted on 2008-05-27 16:31 小牛小虾 阅读(3969) 评论(5)  编辑  收藏

评论

# re: java生成xml文件的时候如何控制xml的缩进格式 2008-05-27 18:41 隔叶黄莺

你可以用 jdom,它可以对输出格式进行美化

Format format = Format.getPrettyFormat();
XMLOutputter outputter = new XMLOutputter(format);

outputter.output(elmemt,writer);  回复  更多评论   

# re: java生成xml文件的时候如何控制xml的缩进格式 2008-05-28 09:18 小牛小虾

@隔叶黄莺
的确,jdom是可以很好的实现,但是我们公司做的是商业产品,所以对使用开源软件有许多限制,只好尽量用java自己的api  回复  更多评论   

# re: java生成xml文件的时候如何控制xml的缩进格式 2008-05-28 21:52 隔叶黄莺

从来只听说商业产品在使用非开源要授权的东西才有许多考虑,没想到你们公司是反其道而行之。只要遵循它的开源协议就行,你们又不需要改 jdom 的源代码,想怎么用就怎么用,看看 WebSphere、WebLogic 等重头的商业产品用了多少开源的东西在里面。

有点不明白你们公司老大的想法,用 Java 自己的 api,那你们开发人员估计只能苦苦受折磨,看着眼边的美味不能受用,只有垂涎的份。

最后,补充一个,Java 也是开源的,报告一下给你们公司上层,看是不要改用 .net 那种不开源的东西。不过有点不幸,.net 也开源了少量的源代码。

话直了些,只是想说明,在这样一个信息大爆炸的时代,唯有保持一种开放的心态,就像此次中国接受国外的救援,不失气节,更受外人赏。

叽叽歪歪,言重了。  回复  更多评论   

# re: java生成xml文件的时候如何控制xml的缩进格式 2008-05-30 10:49 小牛小虾

@隔叶黄莺
我想这位兄弟还是不太了解开源啊.开源正如你所说,是要遵守它的协议,但有的开源协议是要求你一旦使用了它的代码,你就要把你的项目也开源,否则就可以控告你.websphere,weblogic用的开源都是仔细斟酌过其协议的,或者和代码的拥有者达成了一致.
我想你也用过很多免费软件吧,很多软件都会在安装的时候有一个声明(估计你是next过去了),说明该软件你可以免费用,但不能用作商务用途.所以很多大公司不得不去买商务软件而不敢用免费的(除非跟软件作者达成一致)
最后,补充一下,Java是开源的,而且它在使用协议中规定了可以用于商业软件开发所以很多公司才敢用的,没有这一点,就算是开源的也没有几个人敢用.还有.net的所谓开源了少量代码其实完全可以无视,windows还开源了少量代码呢?你能根据那些代码写成xp来吗?这其实只是像微软这样的公司的一个秀而已.
话直了些,只是想说明,软件公司永远都会把自己的代码当成生命线,我们当然要保持开放的心态,但是在具体的产品开发中,我们必须要确保我们使用的东西是干净的,中国必将会走向一个保护知识产权的时代.开源是好,它是顶级程序员的天堂,它可以指明软件发展的方向,但真正的可以赚钱的商业产品,开源肯定是做不过微软,google,ibm的
叽叽歪歪,言重了
  回复  更多评论   

# re: java生成xml文件的时候如何控制xml的缩进格式 2008-05-30 18:44 隔叶黄莺

有的开源协议是要求你一旦使用了它的代码,你就要把你的项目也开源,否则就可以控告你

没有这样的开源协议。  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 
<2008年5月>
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

导航

统计

常用链接

留言簿(6)

随笔档案

文章档案

eclipse

搜索

最新评论

阅读排行榜

评论排行榜