java生成xml文件的時(shí)候如何控制xml的縮進(jìn)格式

          使用java自帶的xml api生成的xml文件,其格式都是沒(méi)有縮進(jìn)的,每個(gè)element都是頂?shù)阶钋懊?今天終于找到了比較好的處理方法,趕緊記下來(lái).

          使用Java標(biāo)準(zhǔn)的JAXP來(lái)輸出可以使用:
          Transformer transformer = TransformerFactory.newInstance().newTransformer();
          transformer.setOutputProperty(OutputKeys.INDENT, "yes");
          transformer.transform(new DOMSource(document), new StreamResult(outputFile));
          中間的紅色代碼是用于設(shè)置縮進(jìn)的,比較遺憾的是JAXP只抽象出是否設(shè)置縮進(jìn)(indent: yes|no),但并沒(méi)有抽象出設(shè)置縮進(jìn)量長(zhǎng)度的常量(indent-number),所以默認(rèn)的縮進(jìn)量長(zhǎng)度為0。如果有下面這樣一個(gè)xml文檔:<root><a><b>c</b></a></root>會(huì)被格式化為:
          <root>
          <a>
          <b>c</b>
          </a>
          </root>
          由于JAXP只是一個(gè)Java一個(gè)處理XML的框架,根據(jù)實(shí)現(xiàn)的不一樣,可以傳入實(shí)現(xiàn)特定的某個(gè)Key來(lái)設(shè)置縮進(jìn)量。比如在Java 1.4下面,可以通過(guò)下面語(yǔ)句將縮進(jìn)量設(shè)為2:
          ransformer.setOutputProperty(
          "{http://xml.apache.org/xslt}indent-amount", "2");

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

          而在Java 1.5下面,情況就有些復(fù)雜了。Java 1.5集成了JXAP 1.3(Java 1.4集成的是JXAP 1.1,不同之處參見(jiàn)http://java.sun.com/j2se/1.5.0/docs/guide/xml/jaxp/JAXP-Compatibility_150.html),實(shí)現(xiàn)基于Xerces類庫(kù)。由于內(nèi)部實(shí)現(xiàn)上的Bug,導(dǎo)致了設(shè)置縮進(jìn)的不同:
          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)))));
          注意紅色代碼的不同之處。第一句設(shè)置TransformerFactory的indent-number屬性,在Java 1.4下面運(yùn)行會(huì)拋出異常,因?yàn)槠洳恢С衷搶傩裕贘ava 1.5中卻只能通過(guò)該屬性來(lái)設(shè)置縮進(jìn)。后面標(biāo)為紅色的代碼則是由于Sun實(shí)現(xiàn)上的Bug,只有通過(guò)StreamResult(Writer)構(gòu)造函數(shù)生成才能正確設(shè)置縮進(jìn)(通過(guò)OutputStream或者File生成的StreamResult是無(wú)法設(shè)置縮進(jìn)的,其實(shí)現(xiàn)上會(huì)忽略任何非正式的屬性,而僅僅采用rt.jar下面com\sun\org\apache\xml\internal\serializer\output_xml.properties中的配置。詳細(xì)可以在com.sun.org.apache.xml.internal.serializer.ToStream類的setOutputStream方法中加斷點(diǎn)進(jìn)行分析)
          ?
          如果忽略掉可移植性,確認(rèn)綁定在Sun的JRE實(shí)現(xiàn)上面,則可以通過(guò)如下代碼來(lái)更好的實(shí)現(xiàn):
          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包下。

          如果應(yīng)用對(duì)增加一個(gè)300K左右的jar包不敏感的話,我還是強(qiáng)烈推薦用dom4j來(lái)處理xml,其API設(shè)計(jì)的非常易用,寫出來(lái)的代碼比用JXAP寫出來(lái)的代碼漂亮多了,也容易維護(hù),也不會(huì)出現(xiàn)上面那種兩個(gè)Java版本不兼容的問(wèn)題。

          posted on 2008-05-27 16:31 小牛小蝦 閱讀(3993) 評(píng)論(5)  編輯  收藏

          評(píng)論

          # re: java生成xml文件的時(shí)候如何控制xml的縮進(jìn)格式 2008-05-27 18:41 隔葉黃鶯

          你可以用 jdom,它可以對(duì)輸出格式進(jìn)行美化

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

          outputter.output(elmemt,writer);  回復(fù)  更多評(píng)論   

          # re: java生成xml文件的時(shí)候如何控制xml的縮進(jìn)格式 2008-05-28 09:18 小牛小蝦

          @隔葉黃鶯
          的確,jdom是可以很好的實(shí)現(xiàn),但是我們公司做的是商業(yè)產(chǎn)品,所以對(duì)使用開源軟件有許多限制,只好盡量用java自己的api  回復(fù)  更多評(píng)論   

          # re: java生成xml文件的時(shí)候如何控制xml的縮進(jìn)格式 2008-05-28 21:52 隔葉黃鶯

          從來(lái)只聽說(shuō)商業(yè)產(chǎn)品在使用非開源要授權(quán)的東西才有許多考慮,沒(méi)想到你們公司是反其道而行之。只要遵循它的開源協(xié)議就行,你們又不需要改 jdom 的源代碼,想怎么用就怎么用,看看 WebSphere、WebLogic 等重頭的商業(yè)產(chǎn)品用了多少開源的東西在里面。

          有點(diǎn)不明白你們公司老大的想法,用 Java 自己的 api,那你們開發(fā)人員估計(jì)只能苦苦受折磨,看著眼邊的美味不能受用,只有垂涎的份。

          最后,補(bǔ)充一個(gè),Java 也是開源的,報(bào)告一下給你們公司上層,看是不要改用 .net 那種不開源的東西。不過(guò)有點(diǎn)不幸,.net 也開源了少量的源代碼。

          話直了些,只是想說(shuō)明,在這樣一個(gè)信息大爆炸的時(shí)代,唯有保持一種開放的心態(tài),就像此次中國(guó)接受國(guó)外的救援,不失氣節(jié),更受外人賞。

          嘰嘰歪歪,言重了。  回復(fù)  更多評(píng)論   

          # re: java生成xml文件的時(shí)候如何控制xml的縮進(jìn)格式 2008-05-30 10:49 小牛小蝦

          @隔葉黃鶯
          我想這位兄弟還是不太了解開源啊.開源正如你所說(shuō),是要遵守它的協(xié)議,但有的開源協(xié)議是要求你一旦使用了它的代碼,你就要把你的項(xiàng)目也開源,否則就可以控告你.websphere,weblogic用的開源都是仔細(xì)斟酌過(guò)其協(xié)議的,或者和代碼的擁有者達(dá)成了一致.
          我想你也用過(guò)很多免費(fèi)軟件吧,很多軟件都會(huì)在安裝的時(shí)候有一個(gè)聲明(估計(jì)你是next過(guò)去了),說(shuō)明該軟件你可以免費(fèi)用,但不能用作商務(wù)用途.所以很多大公司不得不去買商務(wù)軟件而不敢用免費(fèi)的(除非跟軟件作者達(dá)成一致)
          最后,補(bǔ)充一下,Java是開源的,而且它在使用協(xié)議中規(guī)定了可以用于商業(yè)軟件開發(fā)所以很多公司才敢用的,沒(méi)有這一點(diǎn),就算是開源的也沒(méi)有幾個(gè)人敢用.還有.net的所謂開源了少量代碼其實(shí)完全可以無(wú)視,windows還開源了少量代碼呢?你能根據(jù)那些代碼寫成xp來(lái)嗎?這其實(shí)只是像微軟這樣的公司的一個(gè)秀而已.
          話直了些,只是想說(shuō)明,軟件公司永遠(yuǎn)都會(huì)把自己的代碼當(dāng)成生命線,我們當(dāng)然要保持開放的心態(tài),但是在具體的產(chǎn)品開發(fā)中,我們必須要確保我們使用的東西是干凈的,中國(guó)必將會(huì)走向一個(gè)保護(hù)知識(shí)產(chǎn)權(quán)的時(shí)代.開源是好,它是頂級(jí)程序員的天堂,它可以指明軟件發(fā)展的方向,但真正的可以賺錢的商業(yè)產(chǎn)品,開源肯定是做不過(guò)微軟,google,ibm的
          嘰嘰歪歪,言重了
            回復(fù)  更多評(píng)論   

          # re: java生成xml文件的時(shí)候如何控制xml的縮進(jìn)格式 2008-05-30 18:44 隔葉黃鶯

          有的開源協(xié)議是要求你一旦使用了它的代碼,你就要把你的項(xiàng)目也開源,否則就可以控告你

          沒(méi)有這樣的開源協(xié)議。  回復(fù)  更多評(píng)論   


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          <2008年5月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(6)

          隨筆檔案

          文章檔案

          eclipse

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 韶关市| 拜城县| 西丰县| 台中市| 平谷区| 西平县| 孙吴县| 桓仁| 正阳县| 禄劝| 长海县| 吉水县| 郁南县| 湘阴县| 紫金县| 昆明市| 南澳县| 康平县| 宁武县| 民勤县| 辛集市| 肇庆市| 海口市| 蚌埠市| 泽州县| 怀化市| 泊头市| 云南省| 高碑店市| 绥德县| 苏尼特左旗| 玛沁县| 铜山县| 平凉市| 佛教| 林甸县| 富平县| 鲜城| 杭锦后旗| 涿州市| 砀山县|