Мне нужно уметь красиво печатать XML-строки с помощью API Java, и я нашел несколько решений для этого как в Интернете, так и на этом конкретном веб-сайте. Однако, несмотря на многочисленные попытки заставить это работать с javax.xml.transform.Transformer, это было пока неудачей.
Приведенный ниже код работает только частично, когда строка xml в аргументе не содержит никаких новых строк между элементами xml. Это просто не будет делать. Мне нужно уметь печатать что угодно, при условии, что он правильно сформирован и корректен в формате xml, даже если раньше были красивые печатные строки.
Я получил это (собрал из фрагментов кода, которые я нашел, люди утверждали, что это работает для них):
import java.io.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
public class XMLFormatter {
public static String format(String xml, int indent, boolean omitXmlDeclaration)
throws TransformerException {
if (indent < 0) {
throw new IllegalArgumentException();
}
String ret = null;
StringReader reader = new StringReader(xml);
StringWriter writer = new StringWriter();
try {
TransformerFactory factory = TransformerFactory.newInstance();
factory.setAttribute("indent-number", new Integer(indent));
Transformer transformer = factory.newTransformer();
if (omitXmlDeclaration) {
transformer.setOutputProperty(
OutputKeys.OMIT_XML_DECLARATION, "yes");
}
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(
"{http://xml.apache.org/xslt}indent-amount",
String.valueOf(indent));
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
transformer.transform(
new StreamSource(reader),
new StreamResult(writer));
ret = writer.toString();
} catch (TransformerException ex) {
throw ex;
} finally {
if (reader != null) {
reader.close();
}
try {
if (writer != null) {
writer.close();
}
} catch (IOException ex) {}
}
return ret;
}
public static void main(String[] args) throws TransformerException {
StringBuilder sb = new StringBuilder();
sb.append("<rpc-reply><data><smth/></data></rpc-reply>");
System.out.println(sb.toString());
System.out.println();
System.out.println(XMLFormatter.format(sb.toString(), 4, false));
final String NEWLINE = System.getProperty("line.separator");
sb.setLength(0);
sb.append("<rpc-reply>");sb.append(NEWLINE);
sb.append("<data>");sb.append(NEWLINE);
sb.append("<smth/>");sb.append(NEWLINE);
sb.append("</data>");sb.append(NEWLINE);
sb.append("</rpc-reply>");
System.out.println(sb.toString());
System.out.println();
System.out.println(XMLFormatter.format(sb.toString(), 4, false));
}
}
Этот код не должен беспокоить эти новые строки, не так ли? Это ошибка или я что-то упустил здесь? Вывод для фрагмента кода:
<rpc-reply><data><smth/></data></rpc-reply>
<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply>
<data>
<smth/>
</data>
</rpc-reply>
<rpc-reply>
<data>
<smth/>
</data>
</rpc-reply>
<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply>
<data>
<smth/>
</data>
</rpc-reply>
Насколько я могу судить, мой код отличается от других примеров только тем, что я использую StringWriter и StringReader для метода transform (in, out). Я уже пытался преобразовать xml в ByteArrayOutputStream и даже проанализировать его с помощью DOM, а затем передать его в трансформатор, но результат тот же.
Я был бы очень признателен, если бы знал, почему это работает только для однострочных строк.
Я использую jdk1.6_u24 в сочетании с Netbeans 6.9.1.
Этот вопрос относится (и, вероятно, ко множеству других), но не совпадает с:
Как красиво печатать XML с Java?
отступ XML-текста с помощью Transformer
Отступ XML, созданный с помощью Transformer