Javaの組み込みXMLトランスフォーマーを使用してDOMドキュメントを取得し、結果の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>
考え?
「INDENT」を有効にし、トランスフォーマーのインデント量を設定する必要があります。
t.setOutputProperty(OutputKeys.INDENT, "yes");
t.setOutputProperty("{http://xml.Apache.org/xslt}indent-amount", "2");
更新:
参照: シリアル化の前にDOMから空白のみのテキストノードを削除する方法?
(特に@ marc-novakowski、@ james-murty、@ saadのすべてのメンバーに感謝します):
提案された解決策のどちらも私にはうまくいきませんでした。そこで、私は代替ソリューションを探し続けました。それは、前述の2つと3番目のステップの混合物になりました。
//(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"));
(3)を実行して、XML処理コードの「バグのある」動作を回避する必要があります。
ソース:johnnymac75 @ http://bugs.Sun.com/bugdatabase/view_bug.do?bug_id=6296446
(ソースを間違って引用した場合はお知らせください)
次のコードはJava 7。
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のコメントは役に立ちました。
import com.Sun.org.Apache.xml.internal.serializer.OutputPropertiesFactory
transformer.setOutputProperty(OutputPropertiesFactory.S_KEY_INDENT_AMOUNT, "2");
Transformerをいじるのではなく、Xerces(Apache)ライブラリを使用しました。ライブラリを追加したら、以下のコードを追加します。
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);
インデントが必要な場合は、TransformerFactory
に指定する必要があります。
TransformerFactory tf = TransformerFactory.newInstance();
tf.setAttribute("indent-number", new Integer(2));
Transformer t = tf.newTransformer();
私にとってDOCTYPE_PUBLIC
を追加するとうまくいきました:
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC,"yes");
transformer.setOutputProperty("{http://xml.Apache.org/xslt}indent-amount", "10");