В Java 9 произошли изменения в способе javax.xml.transform.Transformer
с OutputKeys.INDENT
обрабатывать теги CDATA. Короче говоря, в Java 8 тег с именем «test», содержащий некоторые символьные данные, приведет к:
<test><![CDATA[data]]></test>
Но с Java 9 те же самые результаты в
<test>
<![CDATA[data]]>
</test>
Который не тот же XML. См. http://java9.wtf/xml-transformer/ для получения дополнительной информации.
Я понял, что для Java 9 был обходной путь, использующий DocumentBuilderFactory
с setIgnoringElementContentWhitespace=true
, но это больше не работает для Java 11.
Кто-нибудь знает способ справиться с этим в Java 11? Я либо ищу способ предотвратить лишние переводы строки (но все же смогу отформатировать мой XML), либо могу игнорировать их при разборе XML (желательно с использованием SAX).
К сожалению, я не знаю, что на самом деле будет содержать тег CDATA в моем приложении. Он может начинаться или заканчиваться пробелами или символами новой строки, поэтому я не могу просто удалить их при чтении XML или при установке значения в результирующем объекте.
Пример программы для демонстрации проблемы:
public static void main(String[] args) throws TransformerException, ParserConfigurationException, IOException, SAXException
{
String data = "data";
StreamSource source = new StreamSource(new StringReader("<foo><bar><![CDATA[" + data + "]]></bar></foo>"));
StreamResult result = new StreamResult(new StringWriter());
Transformer tform = TransformerFactory.newInstance().newTransformer();
tform.setOutputProperty(OutputKeys.INDENT, "yes");
tform.transform(source, result);
String xml = result.getWriter().toString();
System.out.println(xml); // I expect bar and CDATA to be on same line. This is true for Java 8, false for Java 11
Document document = DocumentBuilderFactory.newInstance()
.newDocumentBuilder()
.parse(new InputSource(new StringReader(xml)));
String resultData = document.getElementsByTagName("bar")
.item(0)
.getTextContent();
System.out.println(data.equals(resultData)); // True for Java 8, false for Java 11
}
РЕДАКТИРОВАТЬ: Для дальнейшего использования, я отправил отчет об ошибке в Oracle: https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8223291