diff --git a/src/main/java/org/simpleframework/xml/stream/Formatter.java b/src/main/java/org/simpleframework/xml/stream/Formatter.java
index d4e4fe25b..ae4c31f5f 100644
--- a/src/main/java/org/simpleframework/xml/stream/Formatter.java
+++ b/src/main/java/org/simpleframework/xml/stream/Formatter.java
@@ -159,17 +159,20 @@ public void writeComment(String comment) throws Exception {
* front of the tag, this is done for all but the first start tag.
*
* @param name this is the name of the start tag to be written
+ * @param indent set to false if indentation should be omitted.
*
* @throws Exception thrown if there is an I/O exception
*/
- public void writeStart(String name, String prefix) throws Exception{
+ public void writeStart(String name, String prefix, boolean indent) throws Exception{
String text = indenter.push();
if(last == Tag.START) {
append('>');
}
flush();
- append(text);
+ if (indent) {
+ append(text);
+ }
append('<');
if(!isEmpty(prefix)) {
@@ -270,17 +273,18 @@ public void writeText(String text, Mode mode) throws Exception{
* some text was written then a full end tag is written.
*
* @param name this is the name of the element to be closed
+ * @param indent set to false if indentation should be omitted.
*
* @throws Exception thrown if there is an I/O exception
*/
- public void writeEnd(String name, String prefix) throws Exception {
+ public void writeEnd(String name, String prefix, boolean indent) throws Exception {
String text = indenter.pop();
if(last == Tag.START) {
write('/');
write('>');
} else {
- if(last != Tag.TEXT) {
+ if(last != Tag.TEXT && indent) {
write(text);
}
if(last != Tag.START) {
diff --git a/src/main/java/org/simpleframework/xml/stream/IndentationMode.java b/src/main/java/org/simpleframework/xml/stream/IndentationMode.java
new file mode 100644
index 000000000..d8f0b5c08
--- /dev/null
+++ b/src/main/java/org/simpleframework/xml/stream/IndentationMode.java
@@ -0,0 +1,6 @@
+package org.simpleframework.xml.stream;
+
+public enum IndentationMode {
+ ENABLED,
+ DISABLED
+}
diff --git a/src/main/java/org/simpleframework/xml/stream/NodeWriter.java b/src/main/java/org/simpleframework/xml/stream/NodeWriter.java
index 731cca083..aed2ddebb 100644
--- a/src/main/java/org/simpleframework/xml/stream/NodeWriter.java
+++ b/src/main/java/org/simpleframework/xml/stream/NodeWriter.java
@@ -231,9 +231,6 @@ public OutputNode writeElement(OutputNode parent, String name) throws Exception
private OutputNode writeStart(OutputNode parent, String name) throws Exception {
OutputNode node = new OutputElement(parent, this, name);
- if(name == null) {
- throw new NodeException("Can not have a null name");
- }
return stack.push(node);
}
@@ -279,8 +276,12 @@ private void writeName(OutputNode node) throws Exception {
String prefix = node.getPrefix(verbose);
String name = node.getName();
+ // Don't indent if it is disabled on the parent.
+ boolean indent = node.getParent() == null || node.getParent()
+ .getIndentationMode() == IndentationMode.ENABLED;
+
if(name != null) {
- writer.writeStart(name, prefix);
+ writer.writeStart(name, prefix, indent);
}
}
@@ -329,7 +330,7 @@ private void writeEnd(OutputNode node) throws Exception {
writeValue(node);
}
if(name != null) {
- writer.writeEnd(name, prefix);
+ writer.writeEnd(name, prefix, node.getIndentationMode() == IndentationMode.ENABLED);
writer.flush();
}
}
diff --git a/src/main/java/org/simpleframework/xml/stream/OutputAttribute.java b/src/main/java/org/simpleframework/xml/stream/OutputAttribute.java
index f0422a394..d094cc174 100644
--- a/src/main/java/org/simpleframework/xml/stream/OutputAttribute.java
+++ b/src/main/java/org/simpleframework/xml/stream/OutputAttribute.java
@@ -350,4 +350,11 @@ public boolean isCommitted() {
public String toString() {
return String.format("attribute %s='%s'", name, value);
}
+
+ public IndentationMode getIndentationMode() {
+ return null;
+ }
+
+ public void setIndentationMode(IndentationMode mode) {
+ }
}
diff --git a/src/main/java/org/simpleframework/xml/stream/OutputDocument.java b/src/main/java/org/simpleframework/xml/stream/OutputDocument.java
index ee21294df..c2b3af20b 100644
--- a/src/main/java/org/simpleframework/xml/stream/OutputDocument.java
+++ b/src/main/java/org/simpleframework/xml/stream/OutputDocument.java
@@ -361,4 +361,11 @@ public void commit() throws Exception {
public boolean isCommitted() {
return stack.isEmpty();
}
+
+ public IndentationMode getIndentationMode() {
+ return null;
+ }
+
+ public void setIndentationMode(IndentationMode mode) {
+ }
}
diff --git a/src/main/java/org/simpleframework/xml/stream/OutputElement.java b/src/main/java/org/simpleframework/xml/stream/OutputElement.java
index 2d06bae62..9dffbb7f4 100644
--- a/src/main/java/org/simpleframework/xml/stream/OutputElement.java
+++ b/src/main/java/org/simpleframework/xml/stream/OutputElement.java
@@ -74,6 +74,13 @@ class OutputElement implements OutputNode {
*/
private Mode mode;
+ /**
+ * The {@link IndentationMode} is used to indicate if the serializer should apply indentation
+ * when writing this node. If the mode is disabled, this node will not be indented. If the mode
+ * is enabled, the indentation set in the {@link Format} will be applied.
+ */
+ private IndentationMode indentationMode;
+
/**
* Constructor for the OutputElement object. This is
* used to create an output element that can create elements for
@@ -91,6 +98,7 @@ public OutputElement(OutputNode parent, NodeWriter writer, String name) {
this.writer = writer;
this.parent = parent;
this.name = name;
+ this.indentationMode = IndentationMode.ENABLED;
}
/**
@@ -389,4 +397,12 @@ public boolean isCommitted() {
public String toString() {
return String.format("element %s", name);
}
+
+ public IndentationMode getIndentationMode() {
+ return indentationMode;
+ }
+
+ public void setIndentationMode(IndentationMode mode) {
+ this.indentationMode = mode;
+ }
}
diff --git a/src/main/java/org/simpleframework/xml/stream/OutputNode.java b/src/main/java/org/simpleframework/xml/stream/OutputNode.java
index 0348461ac..4ec56ff24 100644
--- a/src/main/java/org/simpleframework/xml/stream/OutputNode.java
+++ b/src/main/java/org/simpleframework/xml/stream/OutputNode.java
@@ -201,15 +201,16 @@ public interface OutputNode extends Node {
*/
OutputNode getParent();
- /**
- * This is used to create a child element within the element that
- * this object represents. When a new child is created with this
- * method then the previous child is committed to the document.
- * The created OutputNode object can be used to add
- * attributes to the child element as well as other elements.
- *
- * @param name this is the name of the child element to create
- */
+ /**
+ * This is used to create a child element within the element that this object represents. When a
+ * new child is created with this method then the previous child is committed to the document.
+ * The created OutputNode object can be used to add attributes to the child element
+ * as well as other elements.
+ *
+ * @param name this is the name of the child element to create. If the name is
+ * null, a text node is created, which is useful for creating elements
+ * with mixed content.
+ */
OutputNode getChild(String name) throws Exception;
/**
@@ -240,4 +241,19 @@ public interface OutputNode extends Node {
* @return true if this node has already been committed
*/
boolean isCommitted();
+
+ /**
+ * The {@link IndentationMode} is used to indicate if the serializer should apply indentation
+ * when writing this node. If the mode is disabled, this node will not be indented. If the mode
+ * is enabled, the indentation set in the {@link Format} will be applied. The default is to
+ * enable indentation
+ */
+ IndentationMode getIndentationMode();
+
+ /**
+ * The {@link IndentationMode} is used to indicate if the serializer should apply indentation
+ * when writing this node. If the mode is disabled, this node will not be indented. If the mode
+ * is enabled, the indentation set in the {@link Format} will be applied.
+ */
+ void setIndentationMode(IndentationMode mode);
}
diff --git a/src/test/java/org/simpleframework/xml/stream/DisableIndentationTest.java b/src/test/java/org/simpleframework/xml/stream/DisableIndentationTest.java
new file mode 100644
index 000000000..9b0799dfc
--- /dev/null
+++ b/src/test/java/org/simpleframework/xml/stream/DisableIndentationTest.java
@@ -0,0 +1,32 @@
+package org.simpleframework.xml.stream;
+
+import java.io.StringWriter;
+
+import org.simpleframework.xml.ValidationTestCase;
+
+/**
+ * Indentation can be disabled on individual nodes.
+ */
+public class DisableIndentationTest extends ValidationTestCase {
+ public static final String EXPECTED =
+ "\n"+
+ " B\n" +
+ "";
+
+ public void testMixedContent() throws Exception {
+ StringWriter out = new StringWriter();
+ OutputNode root = NodeBuilder.write(out, new Format(2))
+ .getChild("root");
+
+ OutputNode a = root.getChild("a");
+ a.setIndentationMode(IndentationMode.DISABLED);
+
+ OutputNode b = a.getChild("b");
+ b.setValue("B");
+
+ root.commit();
+ validate(out.toString());
+
+ assertEquals(EXPECTED, out.toString());
+ }
+}
diff --git a/src/test/java/org/simpleframework/xml/stream/MixedContentSerializationTest.java b/src/test/java/org/simpleframework/xml/stream/MixedContentSerializationTest.java
new file mode 100644
index 000000000..174b83236
--- /dev/null
+++ b/src/test/java/org/simpleframework/xml/stream/MixedContentSerializationTest.java
@@ -0,0 +1,31 @@
+package org.simpleframework.xml.stream;
+
+import java.io.StringWriter;
+
+import org.simpleframework.xml.ValidationTestCase;
+
+public class MixedContentSerializationTest extends ValidationTestCase {
+
+ public static final String EXPECTED = "First lineASecond line";
+
+ public void testMixedContent() throws Exception {
+ StringWriter out = new StringWriter();
+ OutputNode root = NodeBuilder.write(out, new Format(0))
+ .getChild("root");
+
+ OutputNode textNode1 = root.getChild(null);
+ textNode1.setValue("First line");
+
+ OutputNode a = root.getChild("a");
+ a.setValue("A");
+
+ OutputNode textNode2 = root.getChild(null);
+ textNode2.setValue("Second line");
+
+ root.commit();
+ validate(out.toString());
+
+ assertEquals(EXPECTED, out.toString());
+ }
+
+}