Skip to content

Commit 05ab2b1

Browse files
shapiroronnyrbri
andauthored
asXml(): emit formatting line breaks only where the document contains whitespace (#1158)
Adjacent elements without whitespace in between no longer gain a fabricated line break, which rendered as a visible space between inline elements after a parse round-trip. Whitespace-only text nodes now mark where the formatting break belongs instead of being silently dropped, so the output follows the whitespace actually present in the document. Co-authored-by: RBRi <rbri@rbri.de>
1 parent 3cf7092 commit 05ab2b1

10 files changed

Lines changed: 61 additions & 53 deletions

File tree

src/changes/changes.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88

99
<body>
1010
<release version="5.3.0" date="July xx, 2026" description="Chrome/Edge 150, Bugfixes">
11+
<action type="fix" dev="Ronny Shapiro">
12+
asXml(): emit formatting line breaks only where the document contains whitespace;
13+
adjacent elements no longer gain a fabricated line break that renders as a space.
14+
</action>
1115
<action type="update" dev="rbri">
1216
Many, many javadoc improvements.
1317
</action>

src/main/java/org/htmlunit/html/DomElement.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ protected boolean printXml(final String indent, final boolean tagBefore, final P
362362

363363
if (hasChildren) {
364364
printWriter.print(">");
365-
final boolean tag = printChildrenAsXml(indent, true, printWriter);
365+
final boolean tag = printChildrenAsXml(indent, false, printWriter);
366366
if (tag) {
367367
printWriter.print("\r\n");
368368
printWriter.print(indent);
@@ -380,7 +380,7 @@ else if (isEmptyXmlTagExpanded()) {
380380
printWriter.print("/>");
381381
}
382382

383-
return true;
383+
return false;
384384
}
385385

386386
/**

src/main/java/org/htmlunit/html/DomText.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,9 @@ protected boolean printXml(final String indent, final boolean tagBefore, final P
141141
printWriter.print(data);
142142
tag = false;
143143
}
144+
else if (data != null && !data.isEmpty()) {
145+
tag = true;
146+
}
144147
return printChildrenAsXml(indent, tag, printWriter);
145148
}
146149

src/test/java/org/htmlunit/WebClient8Test.java

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,45 @@ public void asXml() throws Exception {
5959

6060
try (WebClient webClient = new WebClient(getBrowserVersion(), false, null, -1)) {
6161
final HtmlPage page = loadPage(webClient, html, null, URL_FIRST);
62-
assertEquals("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\r\n<html>\r\n"
63-
+ " <head>\r\n"
64-
+ " <title>foo</title>\r\n"
65-
+ " </head>\r\n"
66-
+ " <body>\r\n"
67-
+ " <div>Hello <b>HtmlUnit</b>\r\n"
68-
+ " </div>\r\n"
69-
+ " </body>\r\n"
70-
+ "</html>",
62+
assertEquals("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\r\n"
63+
+ "<html><head><title>foo</title></head>"
64+
+ "<body><div>Hello <b>HtmlUnit</b></div></body></html>",
65+
page.asXml());
66+
}
67+
}
68+
69+
/**
70+
* @throws Exception if something goes wrong
71+
*/
72+
@Test
73+
public void asXmlNoWhitespaceBetweenAdjacentElements() throws Exception {
74+
final String html = DOCTYPE_HTML
75+
+ "<html><head><title>foo</title></head>"
76+
+ "<body><div><span>a</span><span>b</span></div></body></html>";
77+
78+
try (WebClient webClient = new WebClient(getBrowserVersion(), false, null, -1)) {
79+
final HtmlPage page = loadPage(webClient, html, null, URL_FIRST);
80+
assertEquals("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\r\n"
81+
+ "<html><head><title>foo</title></head>"
82+
+ "<body><div><span>a</span><span>b</span></div></body></html>",
83+
page.asXml());
84+
}
85+
}
86+
87+
/**
88+
* @throws Exception if something goes wrong
89+
*/
90+
@Test
91+
public void asXmlWhitespaceOnlyTextBetweenElements() throws Exception {
92+
final String html = DOCTYPE_HTML
93+
+ "<html><head><title>foo</title></head>"
94+
+ "<body><div><span>a</span> <span>b</span></div></body></html>";
95+
96+
try (WebClient webClient = new WebClient(getBrowserVersion(), false, null, -1)) {
97+
final HtmlPage page = loadPage(webClient, html, null, URL_FIRST);
98+
assertEquals("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\r\n"
99+
+ "<html><head><title>foo</title></head>"
100+
+ "<body><div><span>a</span>\r\n <span>b</span></div></body></html>",
71101
page.asXml());
72102
}
73103
}

src/test/java/org/htmlunit/html/HtmlFormTest.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1199,13 +1199,8 @@ public void asXml_emptyTag() throws Exception {
11991199

12001200
final String xml =
12011201
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\r\n"
1202-
+ "<html>\r\n"
1203-
+ " <head/>\r\n"
1204-
+ " <body>\r\n"
1205-
+ " <form></form>\r\n"
1206-
+ " <div>test</div>\r\n"
1207-
+ " </body>\r\n"
1208-
+ "</html>";
1202+
+ "<html><head/><body>\r\n <form></form>\r\n <div>test</div>\r\n"
1203+
+ " </body></html>";
12091204

12101205
final HtmlPage page = loadPage(html);
12111206
assertEquals(xml, page.asXml());

src/test/java/org/htmlunit/html/HtmlNoScript2Test.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ public class HtmlNoScript2Test extends SimpleWebTestCase {
3434
*/
3535
@Test
3636
@Alerts("<body>\r\n"
37-
+ " <noscript>&lt;div&gt;hello</noscript>\r\n"
38-
+ "</body>")
37+
+ " <noscript>&lt;div&gt;hello</noscript></body>")
3938
public void asXml_jsEnabled() throws Exception {
4039
final String html = DOCTYPE_HTML
4140
+ "<html><body>\n"
@@ -57,10 +56,7 @@ public void asXml_jsDisabled() throws Exception {
5756
+ "</body></html>";
5857

5958
final String expected = "<body>\r\n"
60-
+ " <noscript>\r\n"
61-
+ " <div>hello</div>\r\n"
62-
+ " </noscript>\r\n"
63-
+ "</body>";
59+
+ " <noscript><div>hello</div></noscript></body>";
6460

6561
final WebClient client = getWebClient();
6662
client.getOptions().setJavaScriptEnabled(false);

src/test/java/org/htmlunit/html/HtmlOrderedListTest.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,8 @@ public void asXml() throws Exception {
7070

7171
// assertEquals("<ol id=\"myNode\"></ol>", element.asXml());
7272
assertEquals("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\r\n"
73-
+ "<html>\r\n"
74-
+ " <head/>\r\n"
75-
+ " <body>\r\n"
76-
+ " <ol id=\"myNode\"></ol>\n"
73+
+ "<html><head/><body>\r\n <ol id=\"myNode\"></ol>\n"
7774
+ "foo\n"
78-
+ "</body>\r\n"
79-
+ "</html>", page.asXml());
75+
+ "</body></html>", page.asXml());
8076
}
8177
}

src/test/java/org/htmlunit/html/HtmlPageTest.java

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,14 +1042,9 @@ public void asXml_noscript() throws Exception {
10421042
+ "</body></html>";
10431043

10441044
final String expected = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\r\n"
1045-
+ "<html>\r\n"
1046-
+ " <head/>\r\n"
1047-
+ " <body>\r\n"
1048-
+ " <noscript>"
1049-
+ "&lt;p&gt;&lt;strong&gt;your browser does not support JavaScript&lt;/strong&gt;&lt;/p&gt;"
1050-
+ "</noscript>\r\n"
1051-
+ " </body>\r\n"
1052-
+ "</html>";
1045+
+ "<html><head/><body><noscript>"
1046+
+ "&lt;p&gt;&lt;strong&gt;your browser does not support JavaScript&lt;/strong&gt;&lt;/p&gt;"
1047+
+ "</noscript></body></html>";
10531048

10541049
final HtmlPage page = loadPage(html);
10551050
assertEquals(expected, page.asXml());

src/test/java/org/htmlunit/html/HtmlScriptTest.java

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -110,20 +110,13 @@ public void asXml() throws Exception {
110110
// asXml() should be reusable
111111
final String xml = page.asXml();
112112
assertEquals("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\r\n"
113-
+ "<html>\r\n"
114-
+ " <head>\r\n"
115-
+ " <title>foo</title>\r\n"
116-
+ " </head>\r\n"
117-
+ " <body>\r\n"
118-
+ " <script id=\"script1\">\r\n"
113+
+ "<html><head><title>foo</title></head><body>\r\n <script id=\"script1\">\r\n"
119114
+ "//<![CDATA[\r\n"
120115
+ "\n"
121116
+ " alert('hello');\n"
122117
+ "\r\n"
123118
+ "//]]>\r\n"
124-
+ " </script>\r\n"
125-
+ " </body>\r\n"
126-
+ "</html>",
119+
+ " </script></body></html>",
127120
xml);
128121

129122
loadPageWithAlerts(xml);

src/test/java/org/htmlunit/html/HtmlUnorderedList2Test.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,8 @@ public void asXml() throws Exception {
6868

6969
assertEquals("<ul id=\"myNode\"></ul>", element.asXml());
7070
assertEquals("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\r\n"
71-
+ "<html>\r\n"
72-
+ " <head/>\r\n"
73-
+ " <body>\r\n"
74-
+ " <ul id=\"myNode\"></ul>\n"
71+
+ "<html><head/><body>\r\n <ul id=\"myNode\"></ul>\n"
7572
+ "foo\n"
76-
+ "</body>\r\n"
77-
+ "</html>", page.asXml());
73+
+ "</body></html>", page.asXml());
7874
}
7975
}

0 commit comments

Comments
 (0)