diff --git a/commons-serialize-xml/src/main/java/io/gitlab/jfronny/commons/serialize/xml/NativeXmlWriter.java b/commons-serialize-xml/src/main/java/io/gitlab/jfronny/commons/serialize/xml/NativeXmlWriter.java index 1e124ed..a9b9c4f 100644 --- a/commons-serialize-xml/src/main/java/io/gitlab/jfronny/commons/serialize/xml/NativeXmlWriter.java +++ b/commons-serialize-xml/src/main/java/io/gitlab/jfronny/commons/serialize/xml/NativeXmlWriter.java @@ -26,6 +26,7 @@ public class NativeXmlWriter implements Closeable, Flushable { private boolean usesEmptyNewlineAndIndent; private final List deferredComments = new LinkedList<>(); + private String deferredText = null; private boolean wasText = false; private boolean lenient; @@ -103,22 +104,42 @@ public class NativeXmlWriter implements Closeable, Flushable { throw new IllegalStateException("Nesting problem."); } wasText = false; + boolean simple = false; // true if the last tag only contained simple text if (!deferredComments.isEmpty()) { - beforeValue(); - newline(); - writeDeferredComment(); + if (context == TAG_HEAD && deferredComments.size() == 1) { + out.write('>'); + if (deferredText == null) simple = true; + else newline(); + writeDeferredComment(); + } else { + if (context == TAG_HEAD) out.write('>'); + newline(); + writeDeferredComment(); + } context = TAG_BODY; } + if (deferredText != null) { + if (context == TAG_HEAD) { + out.write('>'); + escapeText(deferredText, true); + context = TAG_BODY; + simple = true; + } else text(deferredText); + deferredText = null; + } + stackSize--; if (context == TAG_BODY) { - newline(); + if (!simple) newline(); + out.write("'); + } else { + out.write("/>"); } - out.write("'); return this; } @@ -208,6 +229,10 @@ public class NativeXmlWriter implements Closeable, Flushable { } public NativeXmlWriter text(String text) throws IOException { + if (peek() == TAG_HEAD && !text.contains("\n") && deferredComments.isEmpty()) { + deferredText = text; + return this; + } text = text == null ? "" : text; if (wasText) comment(""); beforeValue(); @@ -262,7 +287,6 @@ public class NativeXmlWriter implements Closeable, Flushable { private void name(String name) throws IOException { if (name == null) throw new NullPointerException("name == null"); if (stackSize == 0) throw new IllegalStateException("JsonWriter is closed."); - if (peek() != TAG_HEAD) throw new IllegalStateException("Nesting problem."); // Check name for illegal characters int last = 0; int length = name.length(); @@ -283,7 +307,6 @@ public class NativeXmlWriter implements Closeable, Flushable { case FIRST -> {} } } - out.write(' '); if (last < length) out.write(name, last, length - last); } @@ -329,8 +352,13 @@ public class NativeXmlWriter implements Closeable, Flushable { case EMPTY_DOCUMENT: replaceTop(NONEMPTY_DOCUMENT); if (!deferredComments.isEmpty()) { - newline(); writeDeferredComment(); + newline(); + } + if (deferredText != null) { + escapeText(deferredText, true); + newline(); + deferredText = null; } break; case DANGLING_NAME: @@ -343,6 +371,11 @@ public class NativeXmlWriter implements Closeable, Flushable { replaceTop(TAG_BODY); case TAG_BODY: newline(); + if (deferredText != null) { + escapeText(deferredText, true); + newline(); + deferredText = null; + } if (!deferredComments.isEmpty()) { writeDeferredComment(); newline();