2009-09-06 37 views
93

我正在使用Java內置的XML轉換器來獲取DOM文檔並打印出生成的XML。問題是,儘管已經明確設置了參數「indent」,但它並沒有縮進文本。Java:如何縮進由變壓器生成的XML

示例代碼

public class TestXML { 

public static void main(String args[]) throws Exception { 
    ByteArrayOutputStream s; 

    Document d = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); 
    Transformer t = TransformerFactory.newInstance().newTransformer(); 

    Element a,b; 

    a = d.createElement("a"); 
    b = d.createElement("b"); 

    a.appendChild(b); 

    d.appendChild(a); 

    t.setParameter(OutputKeys.INDENT, "yes"); 

    s = new ByteArrayOutputStream(); 

    t.transform(new DOMSource(d),new StreamResult(s)); 

    System.out.println(new String(s.toByteArray())); 

} 
} 

結果

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

期望結果

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

思考?

回答

184

您需要啓用 'INDENT' 和設置縮進量爲變壓器:

t.setOutputProperty(OutputKeys.INDENT, "yes"); 
t.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); 

更新:


參考:How to strip whitespace-only text nodes from a DOM before serialization?

(非常感謝所有成員特別是@ marc-novakowski,@ james-murty和@saad)

+7

哦男子*大滿貫面臨到臺* 感謝 – Mike 2009-09-06 03:48:35

+62

看來愚蠢,我認爲默認縮進爲0,但除了'INDENT =是的'我也必須添加:'t.setOutputProperty(「{http://xml.apache.org/xslt}indent-amount」,「2」);' – lapo 2011-01-28 10:21:48

+1

請注意。此縮進屬性在java 5中不起作用。它在java 7中執行。未在java中嘗試過6 – Hilikus 2013-03-06 17:04:49

4

如果您想要縮進,您必須將其指定爲TransformerFactory

TransformerFactory tf = TransformerFactory.newInstance(); 
tf.setAttribute("indent-number", new Integer(2)); 
Transformer t = tf.newTransformer(); 
19

這兩種建議的解決方案都不適用於我。所以我一直在尋找另一種解決方案,最終成爲前面提到的兩種方法的混合體,第三步。

  1. 設置縮進數到了TransformerFactory
  2. 使變壓器
  3. 縮進與一個作家(或BufferedWriter將)
//(1) 
TransformerFactory tf = TransformerFactory.newInstance(); 
tf.setAttribute("indent-number", new Integer(2)); 

//(2) 
Transformer t = tf.newTransformer(); 
t.setOutputProperty(OutputKeys.INDENT, "yes"); 

//(3) 
t.transform(new DOMSource(doc), 
new StreamResult(new OutputStreamWriter(out, "utf-8")); 

你必須做包裹otuputstream(3 )來解決 xml處理代碼的「錯誤」行爲。

來源:johnnymac75 @http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6296446

(如果我列舉我的源錯誤,請讓我知道)

+3

末行引用中的「out」是什麼至? – mujimu 2011-12-16 23:03:50

+0

步驟1是重要的 – 2012-05-06 08:14:05

+0

'indent-number'在Android上不起作用。 – Peterdk 2013-04-09 15:04:08

13

下面的代碼爲我工作與Java 7我設置縮進(是)和縮進(2)在變壓器(不是變壓器工廠)上運行。

TransformerFactory tf = TransformerFactory.newInstance(); 
Transformer t = tf.newTransformer(); 
t.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); 
t.setOutputProperty(OutputKeys.INDENT, "yes"); 
t.transform(source, result); 

@mabac的設置屬性的解決方案並不適用於我,但@ lapo的評論證明是有幫助的。

+2

這是正確的答案。 – 2012-09-06 19:03:48

4

我使用Xerces(Apache)庫而不是與Transformer混淆。一旦添加了庫,請添加下面的代碼。

OutputFormat format = new OutputFormat(document); 
format.setLineWidth(65); 
format.setIndenting(true); 
format.setIndent(2); 
Writer outxml = new FileWriter(new File("out.xml")); 
XMLSerializer serializer = new XMLSerializer(outxml, format); 
serializer.serialize(document); 
+0

它效果更好,但已棄用。 – rghome 2016-01-11 12:59:01

+0

是的。我嘗試了所有其他的方法與變壓器,但都壞了。整個W3C庫是一團糟。 Xerces工作。 – Tuntable 2017-11-10 07:44:35

5

import com.sun.org.apache.xml.internal.serializer。OutputPropertiesFactory

transformer.setOutputProperty(OutputPropertiesFactory.S_KEY_INDENT_AMOUNT, "2"); 
1

對於我來說加入DOCTYPE_PUBLIC工作:

transformer.setOutputProperty(OutputKeys.INDENT, "yes"); 
transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC,"yes"); 
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "10"); 
+0

transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC,「yes」); 是關鍵 – sector11 2017-06-08 05:18:08