Java: как отступать XML, созданный Transformer
Я использую Java, встроенный в XML-транслятор, чтобы взять документ DOM и распечатать полученный XML. Проблема в том, что он вообще не отступает от текста, несмотря на то, что он явно задал параметр "indent".
пример кода
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>
Мысли?
Ответы
Ответ 1
Вам нужно включить "INDENT" и установить величину отступа для трансформатора:
t.setOutputProperty(OutputKeys.INDENT, "yes");
t.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
Update:
Ссылка: Как удалить текстовые узлы только для пробелов из DOM перед сериализацией?
(Большое спасибо всем участникам, особенно @marc-novakowski, @james-murty и @saad):
Ответ 2
Ни один из предлагаемых решений не работал у меня. Поэтому я продолжал искать альтернативное решение, которое в итоге стало смесью двух ранее упомянутых и третьего шага.
- установить номер отступа в transformerfactory
- включить отступ в трансформаторе
- оберните otuputstream писателем (или буферизованным)
//(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
(Если я неправильно привел свой источник, сообщите мне)
Ответ 3
Следующий код работает для меня с Java 7. Я установил отступ (да) и значение отступа (2) на трансформаторе (не трансформатор factory), чтобы заставить его работать.
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 оказался полезным.
Ответ 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);
Ответ 5
import com.sun.org.apache.xml.internal.serializer.OutputPropertiesFactory
transformer.setOutputProperty(OutputPropertiesFactory.S_KEY_INDENT_AMOUNT, "2");
Ответ 6
Если вам нужен отступ, вы должны указать его на TransformerFactory
.
TransformerFactory tf = TransformerFactory.newInstance();
tf.setAttribute("indent-number", new Integer(2));
Transformer t = tf.newTransformer();
Ответ 7
Для меня добавлено DOCTYPE_PUBLIC
:
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC,"yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "10");