8223291: Whitespace is added to CDATA tags when using OutputKeys.INDENT to format XML
Reviewed-by: dfuchs, lancea
--- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java Wed Jul 03 17:52:56 2019 +0200
+++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java Wed Jul 03 16:30:19 2019 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -40,7 +40,7 @@
* because it is used from another package.
*
* @xsl.usage internal
- * @LastModified: Sept 2018
+ * @LastModified: July 2019
*/
public final class ToHTMLStream extends ToStream
{
@@ -719,7 +719,7 @@
public final void endDocument() throws org.xml.sax.SAXException
{
if (m_doIndent) {
- flushCharactersBuffer();
+ flushCharactersBuffer(false);
}
flushPending();
if (m_doIndent && !m_isprevtext)
@@ -782,7 +782,7 @@
if (m_doIndent) {
// will add extra one if having namespace but no matter
m_childNodeNum++;
- flushCharactersBuffer();
+ flushCharactersBuffer(false);
}
ElemContext elemContext = m_elemContext;
@@ -923,7 +923,7 @@
throws org.xml.sax.SAXException
{
if (m_doIndent) {
- flushCharactersBuffer();
+ flushCharactersBuffer(false);
}
// deal with any pending issues
if (m_cdataTagOpen)
@@ -1645,7 +1645,7 @@
{
if (m_doIndent) {
m_childNodeNum++;
- flushCharactersBuffer();
+ flushCharactersBuffer(false);
}
// Process any pending starDocument and startElement first.
flushPending();
--- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToStream.java Wed Jul 03 17:52:56 2019 +0200
+++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToStream.java Wed Jul 03 16:30:19 2019 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -51,7 +51,7 @@
* serializers (xml, html, text ...) that write output to a stream.
*
* @xsl.usage internal
- * @LastModified: Sept 2018
+ * @LastModified: July 2019
*/
abstract public class ToStream extends SerializerBase {
@@ -1231,7 +1231,7 @@
m_elemContext.m_startTagOpen = false;
}
- if (!m_cdataTagOpen && shouldIndent())
+ if (!m_cdataTagOpen && shouldIndentForText())
indent();
boolean writeCDataBrackets =
@@ -1270,6 +1270,7 @@
closeCDATA();
}
+ m_isprevtext = true;
// time to fire off CDATA event
if (m_tracer != null)
super.fireCDATAEvent(ch, old_start, length);
@@ -1536,11 +1537,13 @@
}
/**
- * Used to flush the buffered characters when indentation is on, this method
- * will be called when the next node is traversed.
+ * Flushes the buffered characters when indentation is on. This method
+ * is called before the next node is traversed.
*
+ * @param isText indicates whether the node to be traversed is text
+ * @throws org.xml.sax.SAXException
*/
- final protected void flushCharactersBuffer() throws SAXException {
+ final protected void flushCharactersBuffer(boolean isText) throws SAXException {
try {
if (shouldFormatOutput() && m_charactersBuffer.isAnyCharactersBuffered()) {
if (m_elemContext.m_isCdataSection) {
@@ -1553,7 +1556,9 @@
return;
}
- m_childNodeNum++;
+ if (!isText) {
+ m_childNodeNum++;
+ }
boolean skipBeginningNewlines = false;
if (shouldIndentForText()) {
indent();
@@ -1846,7 +1851,7 @@
if (m_doIndent) {
m_childNodeNum++;
- flushCharactersBuffer();
+ flushCharactersBuffer(false);
}
if (m_needToCallStartDocument)
@@ -2117,7 +2122,7 @@
return;
if (m_doIndent) {
- flushCharactersBuffer();
+ flushCharactersBuffer(false);
}
// namespaces declared at the current depth are no longer valid
// so get rid of them
@@ -2309,7 +2314,7 @@
return;
if (m_doIndent) {
m_childNodeNum++;
- flushCharactersBuffer();
+ flushCharactersBuffer(false);
}
if (m_elemContext.m_startTagOpen)
{
@@ -2491,8 +2496,7 @@
public void startCDATA() throws org.xml.sax.SAXException
{
if (m_doIndent) {
- m_childNodeNum++;
- flushCharactersBuffer();
+ flushCharactersBuffer(true);
}
m_cdataStartCalled = true;
--- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToXMLStream.java Wed Jul 03 17:52:56 2019 +0200
+++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToXMLStream.java Wed Jul 03 16:30:19 2019 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -40,6 +40,7 @@
* be viewed as internal or package private, this is not an API.
*
* @xsl.usage internal
+ * @LastModified: July 2019
*/
public final class ToXMLStream extends ToStream
{
@@ -200,7 +201,7 @@
public void endDocument() throws org.xml.sax.SAXException
{
if (m_doIndent) {
- flushCharactersBuffer();
+ flushCharactersBuffer(false);
}
flushPending();
if (m_doIndent && !m_isprevtext)
@@ -267,7 +268,7 @@
if (m_doIndent) {
m_childNodeNum++;
- flushCharactersBuffer();
+ flushCharactersBuffer(false);
}
flushPending();
--- a/test/jaxp/javax/xml/jaxp/unittest/common/prettyprint/PrettyPrintTest.java Wed Jul 03 17:52:56 2019 +0200
+++ b/test/jaxp/javax/xml/jaxp/unittest/common/prettyprint/PrettyPrintTest.java Wed Jul 03 16:30:19 2019 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -60,7 +60,7 @@
/*
* @test
- * @bug 6439439 8087303 8174025
+ * @bug 6439439 8087303 8174025 8223291
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
* @run testng/othervm -DrunSecMngr=true common.prettyprint.PrettyPrintTest
* @run testng/othervm common.prettyprint.PrettyPrintTest
@@ -382,7 +382,6 @@
private Document toXmlDocument(String xmlString) throws Exception {
InputSource xmlInputSource = new InputSource(new StringReader(xmlString));
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
- dbf.setValidating(true);
DocumentBuilder xmlDocumentBuilder = dbf.newDocumentBuilder();
Document node = xmlDocumentBuilder.parse(xmlInputSource);
return node;
--- a/test/jaxp/javax/xml/jaxp/unittest/common/prettyprint/xmltest1.out Wed Jul 03 17:52:56 2019 +0200
+++ b/test/jaxp/javax/xml/jaxp/unittest/common/prettyprint/xmltest1.out Wed Jul 03 16:30:19 2019 +0000
@@ -1,3 +1,1 @@
-<a>
- <![CDATA[ ]]>
-</a>
+<a><![CDATA[ ]]></a>
--- a/test/jaxp/javax/xml/jaxp/unittest/common/prettyprint/xmltest2.out Wed Jul 03 17:52:56 2019 +0200
+++ b/test/jaxp/javax/xml/jaxp/unittest/common/prettyprint/xmltest2.out Wed Jul 03 16:30:19 2019 +0000
@@ -1,5 +1,3 @@
-<a>
- <![CDATA[ abc def
+<a><![CDATA[ abc def
line2 &a
- test]]>
-</a>
+ test]]></a>
--- a/test/jaxp/javax/xml/jaxp/unittest/common/prettyprint/xmltest8.out Wed Jul 03 17:52:56 2019 +0200
+++ b/test/jaxp/javax/xml/jaxp/unittest/common/prettyprint/xmltest8.out Wed Jul 03 16:30:19 2019 +0000
@@ -1,6 +1,5 @@
<root>
- t
- <![CDATA[ ]]>
+ t<![CDATA[ ]]>
t
<child1/>
--- a/test/jaxp/javax/xml/jaxp/unittest/transform/OutputPropertiesTest.java Wed Jul 03 17:52:56 2019 +0200
+++ b/test/jaxp/javax/xml/jaxp/unittest/transform/OutputPropertiesTest.java Wed Jul 03 16:30:19 2019 +0000
@@ -24,21 +24,79 @@
package transform;
import java.io.StringReader;
+import java.io.StringWriter;
import java.util.Properties;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.OutputKeys;
import javax.xml.transform.Templates;
+import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.testng.Assert;
+import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
/*
* @test
- * @bug 8219705
+ * @bug 8219705 8223291
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
* @run testng transform.OutputPropertiesTest
* @summary Verifies the output properties are set correctly
*/
public class OutputPropertiesTest {
+ /*
+ DataProvider: for testing indentation
+ Data: xml, expected result
+ */
+ @DataProvider(name = "Indentation")
+ public Object[][] getData() {
+ String mix = "\n" +
+ " abc\n" +
+ " mix\n" +
+ " xyz\n" +
+ " ";
+ return new Object[][]{
+ {"abc<![CDATA[data]]>xyz", "abcdataxyz"},
+ {"abc<![CDATA[ & ]]>xyz", "abc & xyz"},
+ {"<![CDATA[data]]>", "data"},
+ {"abc<mix>mix</mix>xyz", mix}
+ };
+ }
+
+
+ /**
+ * bug 8223291
+ * Verifies that no extra indentation is added for CDATA.
+ * @param xml the xml content to be tested
+ * @param expected the expected result
+ * @throws Exception
+ */
+ @Test(dataProvider = "Indentation")
+ public void testIndentation(String xml, String expected) throws Exception
+ {
+ StreamSource source = new StreamSource(new StringReader("<foo><bar>" + xml + "</bar></foo>"));
+ StreamResult result = new StreamResult(new StringWriter());
+
+ Transformer tform = TransformerFactory.newInstance().newTransformer();
+ tform.setOutputProperty(OutputKeys.INDENT, "yes");
+ tform.transform(source, result);
+
+ String xml1 = result.getWriter().toString();
+
+ Document document = DocumentBuilderFactory.newInstance()
+ .newDocumentBuilder()
+ .parse(new InputSource(new StringReader(xml1)));
+
+ String resultData = document.getElementsByTagName("bar")
+ .item(0)
+ .getTextContent();
+
+ Assert.assertEquals(resultData, expected);
+ }
+
@Test
public void testOutputProperties() throws Exception {
String xslData = "<?xml version='1.0'?>"
@@ -70,4 +128,5 @@
prNames[i] + ": actual: " + value + ", expected: " + prValues[i]);
}
}
+
}