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:
transformer.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版本不兼容的問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章