1. 程式人生 > >DOM解析XML的縮排問題(JAVA)

DOM解析XML的縮排問題(JAVA)

Transformer transformer = TransformerFactory.newInstance().newTransformer(); [color=red]transformer.setOutputProperty(OutputKeys.INDENT, "yes");[/color] transformer.transform(new DOMSource(document), new StreamResult(outputFile)); 中間的紅色程式碼是用於設定縮排的,比較遺憾的是JAXP只抽象出是否設定縮排(indent: yes|no),但並沒有抽象出設定縮排量長度的常量(indent-number),所以預設的縮排量[/size] [size=4]長度為0。如果有下面這樣一個xml文件:c會被格式化為: c 由於JAXP只是一個Java一個處理XML的框架,根據實現的不一樣,可以傳入實現特定的某個Key來設定縮排量。比如在Java 1.4下面,可以通過下面語句將縮排量設為2: ransformer.setOutputProperty( "{[url]http://xml.apache.org/xslt[/url]}indent-amount", "2"); 或 transformer.setOutputProperty( "{[url]http://xml.apache.org/xalan[/url]}indent-amount", "2"); 上面兩句不同之處僅在於名稱空間。[/size] [size=4]而在Java 1.5下面,情況就有些複雜了。Java 1.5集成了JXAP 1.3(Java 1.4整合的是JXAP 1.1),實現基於Xerces類庫。由於內部實現上的Bug,導致了設定縮排的不同: TransformerFactory tf = TransformerFactory.newInstance(); [color=red]tf.setAttribute("indent-number", new Integer(2));[/color] Transformer transformer = tf.newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.transform(new DOMSource(document), [color=red]new StreamResult(new?BufferedWriter(new OutputStreamWriter(new FileOutputStream(outputFile)))));[/color] 注意紅色程式碼的不同之處。第一句設定TransformerFactory的indent-number屬性,在Java 1.4下面執行會丟擲異常,因為其不支援該屬性,而在Java 1.5中卻只能通過該屬性來設[/size][size=4]置縮排。後面標為紅色的程式碼則是由於Sun實現上的Bug,只有通過StreamResult(Writer)建構函式生成才能正確設定縮排通過OutputStream或者File生成的StreamResult是無法[/size][size=4]設定縮排的,其實現上會忽略任何非正式的屬性,而僅僅採用rt.jar下面com/sun/org/apache/xml/internal/serializer/output_xml.properties中的配置。詳細可以在[/size][size=4]com.sun.org.apache.xml.internal.serializer.ToStream類的setOutputStream方法中加斷點進行分析)。實現後[/size] [size=4] c [/size] [color=olive]強烈推薦用dom4j來處理xml,其API設計的非常易用,寫出來的程式碼比用JXAP寫出來的程式碼漂亮多了,也容易維護,也不會出現上面那種兩個Java版本不相容的問題。但華為怕引起版權問題,所以外部包要求儘量少用。