Skip to content

Commit e28ac28

Browse files
committed
major improvements for the asXML() function
1 parent 3295e00 commit e28ac28

23 files changed

+173
-88
lines changed

src/changes/changes.xml

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

99
<body>
1010
<release version="4.14.0" date="July xx, 2025" description="Chrome/Edge 137, Firefox 139, Bugfixes">
11+
<action type="update" dev="rbri">
12+
Major improvements for the asXML() function.
13+
</action>
1114
<action type="update" dev="rbri">
1215
Test suite updated to junit 5 and cleaned up.
1316
</action>

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
*
2525
* @author Marc Guillemot
2626
* @author David K. Taylor
27+
* @author Ronald Brill
2728
*/
2829
public class DomCDataSection extends DomText implements CDATASection {
2930

@@ -57,10 +58,11 @@ public String getNodeName() {
5758
* {@inheritDoc}
5859
*/
5960
@Override
60-
protected void printXml(final String indent, final PrintWriter printWriter) {
61+
protected boolean printXml(final String indent, final boolean tagBefore, final PrintWriter printWriter) {
6162
printWriter.print("<![CDATA[");
6263
printWriter.print(getData());
6364
printWriter.print("]]>");
65+
return true;
6466
}
6567

6668
/**

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

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
*
2525
* @author Karel Kolman
2626
* @author Ahmed Ashour
27+
* @author Ronald Brill
2728
*/
2829
public class DomComment extends DomCharacterData implements Comment {
2930

@@ -58,18 +59,15 @@ public String getNodeName() {
5859
}
5960

6061
/**
61-
* Recursively write the XML data for the node tree starting at <code>node</code>.
62-
*
63-
* @param indent white space to indent child nodes
64-
* @param printWriter writer where child nodes are written
62+
* {@inheritDoc}
6563
*/
6664
@Override
67-
protected void printXml(final String indent, final PrintWriter printWriter) {
65+
protected boolean printXml(final String indent, final boolean tagBefore, final PrintWriter printWriter) {
6866
printWriter.print(indent);
6967
printWriter.print("<!--");
7068
printWriter.print(getData());
7169
printWriter.print("-->");
72-
printChildrenAsXml(indent, printWriter);
70+
return printChildrenAsXml(indent, true, printWriter);
7371
}
7472

7573
/**

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

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -350,28 +350,41 @@ protected void printOpeningTagContentAsXml(final PrintWriter printWriter) {
350350
}
351351

352352
/**
353-
* Recursively write the XML data for the node tree starting at <code>node</code>.
354-
*
355-
* @param indent white space to indent child nodes
356-
* @param printWriter writer where child nodes are written
353+
* {@inheritDoc}
357354
*/
358355
@Override
359-
protected void printXml(final String indent, final PrintWriter printWriter) {
356+
protected boolean printXml(final String indent, final boolean tagBefore, final PrintWriter printWriter) {
360357
final boolean hasChildren = getFirstChild() != null;
361-
printWriter.print(indent + "<");
362-
printOpeningTagContentAsXml(printWriter);
363358

364-
if (hasChildren || isEmptyXmlTagExpanded()) {
365-
printWriter.print(">\r\n");
366-
printChildrenAsXml(indent, printWriter);
359+
if (tagBefore) {
360+
printWriter.print("\r\n");
367361
printWriter.print(indent);
362+
}
363+
364+
printWriter.print('<');
365+
printOpeningTagContentAsXml(printWriter);
366+
367+
if (hasChildren) {
368+
printWriter.print(">");
369+
final boolean tag = printChildrenAsXml(indent, true, printWriter);
370+
if (tag) {
371+
printWriter.print("\r\n");
372+
printWriter.print(indent);
373+
}
368374
printWriter.print("</");
369375
printWriter.print(getTagName());
370-
printWriter.print(">\r\n");
376+
printWriter.print(">");
377+
}
378+
else if (isEmptyXmlTagExpanded()) {
379+
printWriter.print("></");
380+
printWriter.print(getTagName());
381+
printWriter.print(">");
371382
}
372383
else {
373-
printWriter.print("/>\r\n");
384+
printWriter.print("/>");
374385
}
386+
387+
return true;
375388
}
376389

377390
/**

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

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -789,12 +789,14 @@ public String asXml() {
789789

790790
final StringWriter stringWriter = new StringWriter();
791791
try (PrintWriter printWriter = new PrintWriter(stringWriter)) {
792+
boolean tag = false;
792793
if (charsetName != null && this instanceof HtmlHtml) {
793794
printWriter.print("<?xml version=\"1.0\" encoding=\"");
794795
printWriter.print(charsetName);
795-
printWriter.print("\"?>\r\n");
796+
printWriter.print("\"?>");
797+
tag = true;
796798
}
797-
printXml("", printWriter);
799+
printXml("", tag, printWriter);
798800
return stringWriter.toString();
799801
}
800802
}
@@ -803,27 +805,35 @@ public String asXml() {
803805
* Recursively writes the XML data for the node tree starting at <code>node</code>.
804806
*
805807
* @param indent white space to indent child nodes
808+
* @param tagBefore true if the last thing printed was a tag
806809
* @param printWriter writer where child nodes are written
810+
* @return true if the last thing printed was a tag
807811
*/
808-
protected void printXml(final String indent, final PrintWriter printWriter) {
809-
printWriter.print(indent);
812+
protected boolean printXml(final String indent, final boolean tagBefore, final PrintWriter printWriter) {
813+
if (tagBefore) {
814+
printWriter.print("\r\n");
815+
printWriter.print(indent);
816+
}
810817
printWriter.print(this);
811-
printWriter.print("\r\n");
812-
printChildrenAsXml(indent, printWriter);
818+
return printChildrenAsXml(indent, false, printWriter);
813819
}
814820

815821
/**
816822
* Recursively writes the XML data for the node tree starting at <code>node</code>.
817823
*
818824
* @param indent white space to indent child nodes
825+
* @param tagBefore true if the last thing printed was a tag
819826
* @param printWriter writer where child nodes are written
827+
* @return true if the last thing printed was a tag
820828
*/
821-
protected void printChildrenAsXml(final String indent, final PrintWriter printWriter) {
829+
protected boolean printChildrenAsXml(final String indent, final boolean tagBefore, final PrintWriter printWriter) {
822830
DomNode child = getFirstChild();
831+
boolean tag = tagBefore;
823832
while (child != null) {
824-
child.printXml(indent + " ", printWriter);
833+
tag = child.printXml(indent + " ", tag, printWriter);
825834
child = child.getNextSibling();
826835
}
836+
return tag;
827837
}
828838

829839
/**

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
* Wrapper for the DOM node ProcessingInstruction.
2525
*
2626
* @author Ahmed Ashour
27+
* @author Ronald Brill
2728
*/
2829
public class DomProcessingInstruction extends DomNode implements ProcessingInstruction {
2930

@@ -112,12 +113,13 @@ public void setTextContent(final String textContent) {
112113
* {@inheritDoc}
113114
*/
114115
@Override
115-
protected void printXml(final String indent, final PrintWriter printWriter) {
116+
protected boolean printXml(final String indent, final boolean tagBefore, final PrintWriter printWriter) {
116117
printWriter.print("<?");
117118
printWriter.print(getTarget());
118119
printWriter.print(" ");
119120
printWriter.print(getData());
120121
printWriter.print("?>");
122+
return true;
121123
}
122124

123125
/**

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

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -128,23 +128,20 @@ public String getNodeName() {
128128
}
129129

130130
/**
131-
* Recursively writes the XML data for the node tree starting at <code>node</code>.
132-
*
133-
* @param indent white space to indent child nodes
134-
* @param printWriter writer where child nodes are written
131+
* {@inheritDoc}
135132
*/
136133
@Override
137-
protected void printXml(final String indent, final PrintWriter printWriter) {
134+
protected boolean printXml(final String indent, final boolean tagBefore, final PrintWriter printWriter) {
138135
String data = getData();
136+
boolean tag = tagBefore;
139137
if (org.apache.commons.lang3.StringUtils.isNotBlank(data)) {
140-
printWriter.print(indent);
141138
if (!(getParentNode() instanceof HtmlStyle) || !data.startsWith("<!--") || !data.endsWith("-->")) {
142139
data = StringUtils.escapeXmlChars(data);
143140
}
144141
printWriter.print(data);
145-
printWriter.print("\r\n");
142+
tag = false;
146143
}
147-
printChildrenAsXml(indent, printWriter);
144+
return printChildrenAsXml(indent, tag, printWriter);
148145
}
149146

150147
/**

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -245,25 +245,25 @@ protected boolean isEmptyXmlTagExpanded() {
245245
* {@inheritDoc}
246246
*/
247247
@Override
248-
protected void printChildrenAsXml(final String indent, final PrintWriter printWriter) {
248+
protected boolean printChildrenAsXml(final String indent, final boolean tagBefore, final PrintWriter printWriter) {
249249
final DomCharacterData textNode = (DomCharacterData) getFirstChild();
250250
if (textNode == null) {
251-
return;
251+
return tagBefore;
252252
}
253253

254254
final String data = textNode.getData();
255+
printWriter.print("\r\n");
255256
if (data.contains("//<![CDATA[")) {
256257
printWriter.print(data);
257-
printWriter.print("\r\n");
258258
}
259259
else {
260260
printWriter.print("//<![CDATA[");
261261
printWriter.print("\r\n");
262262
printWriter.print(data);
263263
printWriter.print("\r\n");
264264
printWriter.print("//]]>");
265-
printWriter.print("\r\n");
266265
}
266+
return true;
267267
}
268268

269269
/**

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

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,41 @@ protected boolean isEmptyXmlTagExpanded() {
6969
return true;
7070
}
7171

72+
/**
73+
* {@inheritDoc}
74+
*/
7275
@Override
73-
protected void printChildrenAsXml(final String indent, final PrintWriter printWriter) {
74-
domDocumentFragment_.printChildrenAsXml(indent, printWriter);
76+
protected boolean printXml(final String indent, final boolean tagBefore, final PrintWriter printWriter) {
77+
final boolean hasChildren = domDocumentFragment_.getFirstChild() != null;
78+
79+
if (tagBefore) {
80+
printWriter.print("\r\n");
81+
printWriter.print(indent);
82+
}
83+
84+
printWriter.print('<');
85+
printOpeningTagContentAsXml(printWriter);
86+
87+
if (hasChildren) {
88+
printWriter.print(">");
89+
final boolean tag = domDocumentFragment_.printChildrenAsXml(indent, tagBefore, printWriter);
90+
if (tag) {
91+
printWriter.print("\r\n");
92+
printWriter.print(indent);
93+
}
94+
printWriter.print("</");
95+
printWriter.print(getTagName());
96+
printWriter.print(">");
97+
}
98+
else if (isEmptyXmlTagExpanded()) {
99+
printWriter.print("></");
100+
printWriter.print(getTagName());
101+
printWriter.print(">");
102+
}
103+
else {
104+
printWriter.print("/>");
105+
}
106+
107+
return true;
75108
}
76109
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,13 +427,14 @@ public void setSelectionEnd(final int selectionEnd) {
427427
* {@inheritDoc}
428428
*/
429429
@Override
430-
protected void printXml(final String indent, final PrintWriter printWriter) {
430+
protected boolean printXml(final String indent, final boolean tagBefore, final PrintWriter printWriter) {
431431
printWriter.print(indent + "<");
432432
printOpeningTagContentAsXml(printWriter);
433433

434434
printWriter.print(">");
435435
printWriter.print(org.htmlunit.util.StringUtils.escapeXml(getText()));
436436
printWriter.print("</textarea>");
437+
return true;
437438
}
438439

439440
/**

0 commit comments

Comments
 (0)