Поскольку перемещение в java 1.7 Xml Document Element не является отступом
Я пытаюсь сделать отступ XML, созданный Transformer.
Все DOM Node являются отступом, как ожидалось, за исключением первого Node - элемента документа.
элемент документа не запускается в новой строке, а просто согласуется сразу после объявления XML.
Эта ошибка возникает, когда я перешел на java 1.7, при использовании java 1.6 или 1.5 этого не происходит.
Мой код:
ByteArrayOutputStream s = new OutputStreamWriter(out, "utf-8");
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount","4");
transformer.transform(new DOMSource(doc), new StreamResult(s));
Выход:
<?xml version="1.0" encoding="UTF-8"?><a>
<b>bbbbb</b>
</a>
Кто-нибудь знает, почему?
Кстати,
когда я добавляю свойство
transformer.setOutputProperty(OutputKeys.STANDALONE, "yes");
Работает так, как ожидалось, но объявление xml изменяется,
теперь у него есть автономное свойство, и я не хочу изменять объявление xml.
Ответы
Ответ 1
Хорошо,
Я нашел в Java API следующее:
Если указано свойство doctype-system, метод вывода xml должен вывести объявление типа документа непосредственно перед первым элементом.
SO Я использовал это свойство
transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "yes");
и он решает мою проблему без изменения моего объявления xml.
Спасибо.
Ответ 2
Для меня написать декларацию XML в Writer
или OutputStream
перед тем, как писать XML и сказать, что трансформатор пропустить объявление, это единственное, что сработало. Единственное другое решение для сохранения интервала - это библиотека VTD-XML.
StringBuilder sb = new StringBuilder();
sb.append("<?xml version=\"").append(doc.getXmlVersion()).append("\"");
sb.append(" encoding=\"").append(doc.getXmlEncoding()).append("\"");
if (doc.getXmlStandalone()) {
sb.append(" standalone=\"").append("" + doc.getXmlStandalone()).append("\"");
}
sb.append("?>").append("\n");
writer.write(sb.toString());
TransformerFactory tf = TransformerFactory.newInstance();
try {
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
}
catch (Exception e) {
//snipped out for brevity
}
Ответ 3
Это, кажется, проблема (ошибка) реализации XML в Java. Единственный способ получить строку после объявления XML - явно указать атрибут standalone
. Вы можете установить его на no
, что является неявным значением по умолчанию, даже если оно совершенно не имеет значения, если не используется DTD.
Ответ 4
Xalan в какой-то момент изменил поведение символа новой строки после объявления XML.
OpenJDK (и, следовательно, Oracle JDK тоже) внедрил обходной путь для этой проблемы. Это обходное решение можно включить, установив специальное свойство в объект Transformer
:
try {
transformer.setOutputProperty("http://www.oracle.com/xml/is-standalone", "yes");
} catch (IllegalArgumentException e) {
// Might be thrown by JDK versions not implementing the workaround.
}
Таким образом, старое поведение (печать символа новой строки после объявления XML) восстанавливается без добавления автономного атрибута в декларацию XML.