StAX XML форматирование в Java
Возможно ли использовать StAX (в частности, woodstox) для форматирования выходного xml с помощью новых строк и вкладок, то есть в виде:
someData Element2> Element1>
вместо:
someData element2> element1>
Если это невозможно в Вудстоксе, есть ли другие легковесные либы, которые могут это сделать?
10 ответов
Через JDK: transformer.setOutputProperty(OutputKeys.INDENT, "yes");
,
Есть com.sun.xml.txw2.output.IndentingXMLStreamWriter
XMLOutputFactory xmlof = XMLOutputFactory.newInstance();
XMLStreamWriter writer = new IndentingXMLStreamWriter(xmlof.createXMLStreamWriter(out));
Использование JDK Transformer:
public String transform(String xml) throws XMLStreamException, TransformerException
{
Transformer t = TransformerFactory.newInstance().newTransformer();
t.setOutputProperty(OutputKeys.INDENT, "yes");
t.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
Writer out = new StringWriter();
t.transform(new StreamSource(new StringReader(xml)), new StreamResult(out));
return out.toString();
}
Вместо того чтобы полагаться на класс com.sun..., который может исчезнуть (или переименовать в класс com.oracle...), я рекомендую загрузить служебные классы StAX с java.net. Этот пакет содержит класс IndentingXMLStreamWriter, который прекрасно работает. (Источник и Javadoc включены в загрузку.)
Как насчет StaxMate:
http://www.cowtowncoder.com/blog/archives/2006/09/entry_21.html
Хорошо работает с Woodstox, быстрым использованием памяти с небольшим объемом памяти (без встроенного дерева в памяти) и такими отступами:
SMOutputFactory sf = new SMOutputFactory(XMLOutputFactory.newInstance());
SMOutputDocument doc = sf.createOutputDocument(new FileOutputStream("output.xml"));
doc.setIndentation("\n ", 1, 2); // for unix linefeed, 2 spaces per level
// write doc like:
SMOutputElement root = doc.addElement("element1");
root.addElement("element2").addCharacters("someData");
doc.closeRoot(); // important, flushes, closes output
Если вы используете XMLEventWriter, то более простой способ сделать это:
XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
XMLEventWriter writer = outputFactory.createXMLEventWriter(w);
XMLEventFactory eventFactory = XMLEventFactory.newInstance();
Characters newLine = eventFactory.createCharacters("\n");
writer.add(startRoot);
writer.add(newLine);
Не уверен насчет Stax, но здесь недавно обсуждалась красивая печать XML
это была моя попытка найти решение
Как красиво печатать XML из Java?
используя метод org.dom4j.io.OutputFormat.createPrettyPrint()
Если вы используете метод итерации (XMLEventReader), не можете ли вы просто присоединить символ новой строки '\n' к соответствующим XMLEvents при записи в ваш XML-файл?
В Spring Batch для этого требуется подкласс, так как этот JIRA BATCH-1867
public class IndentingStaxEventItemWriter<T> extends StaxEventItemWriter<T> {
@Setter
@Getter
private boolean indenting = true;
@Override
protected XMLEventWriter createXmlEventWriter( XMLOutputFactory outputFactory, Writer writer) throws XMLStreamException {
if ( isIndenting() ) {
return new IndentingXMLEventWriter( super.createXmlEventWriter( outputFactory, writer ) );
}
else {
return super.createXmlEventWriter( outputFactory, writer );
}
}
}
Но это требует дополнительной зависимости, потому что Spring Batch не включает код для отступа вывода StAX:
<dependency>
<groupId>net.java.dev.stax-utils</groupId>
<artifactId>stax-utils</artifactId>
<version>20070216</version>
</dependency>