You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2017/02/23 23:14:45 UTC

incubator-juneau git commit: Fix HTML serialization of empty non-void elements.

Repository: incubator-juneau
Updated Branches:
  refs/heads/master aba451906 -> c32ae82a4


Fix HTML serialization of empty non-void elements.

Project: http://git-wip-us.apache.org/repos/asf/incubator-juneau/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-juneau/commit/c32ae82a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-juneau/tree/c32ae82a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-juneau/diff/c32ae82a

Branch: refs/heads/master
Commit: c32ae82a4ba3d1e69f3549626e7facf3756fcde2
Parents: aba4519
Author: JamesBognar <ja...@apache.org>
Authored: Thu Feb 23 18:14:48 2017 -0500
Committer: JamesBognar <ja...@apache.org>
Committed: Thu Feb 23 18:14:48 2017 -0500

----------------------------------------------------------------------
 .../apache/juneau/dto/html5/Html5ComboTest.java | 36 ++++++++++----------
 .../org/apache/juneau/html/BasicHtmlTest.java   | 24 ++++++-------
 .../apache/juneau/xml/InvalidXmlBeansTest.java  |  8 ++---
 .../java/org/apache/juneau/dto/html5/Area.java  |  2 +-
 .../java/org/apache/juneau/dto/html5/Base.java  |  2 +-
 .../java/org/apache/juneau/dto/html5/Br.java    |  2 +-
 .../java/org/apache/juneau/dto/html5/Col.java   |  2 +-
 .../java/org/apache/juneau/dto/html5/Embed.java |  2 +-
 .../java/org/apache/juneau/dto/html5/Hr.java    |  2 +-
 .../juneau/dto/html5/HtmlElementEmpty.java      | 19 -----------
 .../juneau/dto/html5/HtmlElementVoid.java       | 25 ++++++++++++++
 .../java/org/apache/juneau/dto/html5/Img.java   |  2 +-
 .../java/org/apache/juneau/dto/html5/Input.java |  2 +-
 .../org/apache/juneau/dto/html5/Keygen.java     |  2 +-
 .../java/org/apache/juneau/dto/html5/Link.java  |  2 +-
 .../java/org/apache/juneau/dto/html5/Meta.java  |  2 +-
 .../java/org/apache/juneau/dto/html5/Param.java |  2 +-
 .../org/apache/juneau/dto/html5/Source.java     |  2 +-
 .../java/org/apache/juneau/dto/html5/Track.java |  2 +-
 .../java/org/apache/juneau/dto/html5/Wbr.java   |  2 +-
 .../juneau/html/HtmlSerializerSession.java      |  5 +++
 .../java/org/apache/juneau/xml/XmlBeanMeta.java |  9 +++--
 .../org/apache/juneau/xml/XmlSerializer.java    | 22 ++++++++----
 .../apache/juneau/xml/XmlSerializerSession.java | 13 +++++++
 .../apache/juneau/xml/annotation/XmlFormat.java | 16 ++++++++-
 juneau-core/src/main/javadoc/overview.html      |  2 ++
 26 files changed, 132 insertions(+), 77 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c32ae82a/juneau-core-test/src/test/java/org/apache/juneau/dto/html5/Html5ComboTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/dto/html5/Html5ComboTest.java b/juneau-core-test/src/test/java/org/apache/juneau/dto/html5/Html5ComboTest.java
index 3614fad..15d45d2 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/dto/html5/Html5ComboTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/dto/html5/Html5ComboTest.java
@@ -142,9 +142,9 @@ public class Html5ComboTest extends ComboTest {
 				/* XmlT */		"<a href='http://foo'/>",
 				/* XmlR */		"<a href='http://foo'/>\n",
 				/* XmlNs */		"<a href='http://foo'/>",
-				/* Html */		"<a href='http://foo'/>",
-				/* HtmlT */		"<a href='http://foo'/>",
-				/* HtmlR */		"<a href='http://foo'/>\n",
+				/* Html */		"<a href='http://foo'></a>",
+				/* HtmlT */		"<a href='http://foo'></a>",
+				/* HtmlR */		"<a href='http://foo'></a>\n",
 				/* Uon */		"(_type=a,a=(href=http://foo))",
 				/* UonT */		"(t=a,a=(href=http://foo))",
 				/* UonR */		"(\n\t_type=a,\n\ta=(\n\t\thref=http://foo\n\t)\n)",
@@ -217,9 +217,9 @@ public class Html5ComboTest extends ComboTest {
 				/* XmlT */		"<address/>",
 				/* XmlR */		"<address/>\n",
 				/* XmlNs */		"<address/>",
-				/* Html */		"<address/>",
-				/* HtmlT */		"<address/>",
-				/* HtmlR */		"<address/>\n",
+				/* Html */		"<address></address>",
+				/* HtmlT */		"<address></address>",
+				/* HtmlR */		"<address></address>\n",
 				/* Uon */		"(_type=address)",
 				/* UonT */		"(t=address)",
 				/* UonR */		"(\n\t_type=address\n)",
@@ -497,9 +497,9 @@ public class Html5ComboTest extends ComboTest {
 				/* XmlT */		"<canvas width='100' height='200'/>",
 				/* XmlR */		"<canvas width='100' height='200'/>\n",
 				/* XmlNs */		"<canvas width='100' height='200'/>",
-				/* Html */		"<canvas width='100' height='200'/>",
-				/* HtmlT */		"<canvas width='100' height='200'/>",
-				/* HtmlR */		"<canvas width='100' height='200'/>\n",
+				/* Html */		"<canvas width='100' height='200'></canvas>",
+				/* HtmlT */		"<canvas width='100' height='200'></canvas>",
+				/* HtmlR */		"<canvas width='100' height='200'></canvas>\n",
 				/* Uon */		"(_type=canvas,a=(width=100,height=200))",
 				/* UonT */		"(t=canvas,a=(width=100,height=200))",
 				/* UonR */		"(\n\t_type=canvas,\n\ta=(\n\t\twidth=100,\n\t\theight=200\n\t)\n)",
@@ -575,9 +575,9 @@ public class Html5ComboTest extends ComboTest {
 				/* XmlT */		"<datalist id='foo'><option value='One'/><option value='Two'/></datalist>",
 				/* XmlR */		"<datalist id='foo'>\n\t<option value='One'/>\n\t<option value='Two'/>\n</datalist>\n",
 				/* XmlNs */		"<datalist id='foo'><option value='One'/><option value='Two'/></datalist>",
-				/* Html */		"<datalist id='foo'><option value='One'/><option value='Two'/></datalist>",
-				/* HtmlT */		"<datalist id='foo'><option value='One'/><option value='Two'/></datalist>",
-				/* HtmlR */		"<datalist id='foo'>\n\t<option value='One'/>\n\t<option value='Two'/>\n</datalist>\n",
+				/* Html */		"<datalist id='foo'><option value='One'></option><option value='Two'></option></datalist>",
+				/* HtmlT */		"<datalist id='foo'><option value='One'></option><option value='Two'></option></datalist>",
+				/* HtmlR */		"<datalist id='foo'>\n\t<option value='One'></option>\n\t<option value='Two'></option>\n</datalist>\n",
 				/* Uon */		"(_type=datalist,a=(id=foo),c=@((_type=option,a=(value=One)),(_type=option,a=(value=Two))))",
 				/* UonT */		"(t=datalist,a=(id=foo),c=@((t=option,a=(value=One)),(t=option,a=(value=Two))))",
 				/* UonR */		"(\n\t_type=datalist,\n\ta=(\n\t\tid=foo\n\t),\n\tc=@(\n\t\t(\n\t\t\t_type=option,\n\t\t\ta=(\n\t\t\t\tvalue=One\n\t\t\t)\n\t\t),\n\t\t(\n\t\t\t_type=option,\n\t\t\ta=(\n\t\t\t\tvalue=Two\n\t\t\t)\n\t\t)\n\t)\n)",
@@ -1204,9 +1204,9 @@ public class Html5ComboTest extends ComboTest {
 				/* XmlT */		"<form action='testform' oninput='x.value=parseInt(a.value)+parseInt(b.value)'>0<input type='range' id='a' value='50'/>+<input type='number' id='b' value='50'/>=<output name='x' for='a b'/></form>",
 				/* XmlR */		"<form action='testform' oninput='x.value=parseInt(a.value)+parseInt(b.value)'>0<input type='range' id='a' value='50'/>+<input type='number' id='b' value='50'/>=<output name='x' for='a b'/></form>\n",
 				/* XmlNs */		"<form action='testform' oninput='x.value=parseInt(a.value)+parseInt(b.value)'>0<input type='range' id='a' value='50'/>+<input type='number' id='b' value='50'/>=<output name='x' for='a b'/></form>",
-				/* Html */		"<form action='testform' oninput='x.value=parseInt(a.value)+parseInt(b.value)'>0<input type='range' id='a' value='50'/>+<input type='number' id='b' value='50'/>=<output name='x' for='a b'/></form>",
-				/* HtmlT */		"<form action='testform' oninput='x.value=parseInt(a.value)+parseInt(b.value)'>0<input type='range' id='a' value='50'/>+<input type='number' id='b' value='50'/>=<output name='x' for='a b'/></form>",
-				/* HtmlR */		"<form action='testform' oninput='x.value=parseInt(a.value)+parseInt(b.value)'>0<input type='range' id='a' value='50'/>+<input type='number' id='b' value='50'/>=<output name='x' for='a b'/></form>\n",
+				/* Html */		"<form action='testform' oninput='x.value=parseInt(a.value)+parseInt(b.value)'>0<input type='range' id='a' value='50'/>+<input type='number' id='b' value='50'/>=<output name='x' for='a b'></output></form>",
+				/* HtmlT */		"<form action='testform' oninput='x.value=parseInt(a.value)+parseInt(b.value)'>0<input type='range' id='a' value='50'/>+<input type='number' id='b' value='50'/>=<output name='x' for='a b'></output></form>",
+				/* HtmlR */		"<form action='testform' oninput='x.value=parseInt(a.value)+parseInt(b.value)'>0<input type='range' id='a' value='50'/>+<input type='number' id='b' value='50'/>=<output name='x' for='a b'></output></form>\n",
 				/* Uon */		"(_type=form,a=(action=testform,oninput='x.value=parseInt(a.value)+parseInt(b.value)'),c=@(0,(_type=input,a=(type=range,id=a,value=50)),+,(_type=input,a=(type=number,id=b,value=50)),'=',(_type=output,a=(name=x,for='a b'))))",
 				/* UonT */		"(t=form,a=(action=testform,oninput='x.value=parseInt(a.value)+parseInt(b.value)'),c=@(0,(t=input,a=(type=range,id=a,value=50)),+,(t=input,a=(type=number,id=b,value=50)),'=',(t=output,a=(name=x,for='a b'))))",
 				/* UonR */		"(\n\t_type=form,\n\ta=(\n\t\taction=testform,\n\t\toninput='x.value=parseInt(a.value)+parseInt(b.value)'\n\t),\n\tc=@(\n\t\t0,\n\t\t(\n\t\t\t_type=input,\n\t\t\ta=(\n\t\t\t\ttype=range,\n\t\t\t\tid=a,\n\t\t\t\tvalue=50\n\t\t\t)\n\t\t),\n\t\t+,\n\t\t(\n\t\t\t_type=input,\n\t\t\ta=(\n\t\t\t\ttype=number,\n\t\t\t\tid=b,\n\t\t\t\tvalue=50\n\t\t\t)\n\t\t),\n\t\t'=',\n\t\t(\n\t\t\t_type=output,\n\t\t\ta=(\n\t\t\t\tname=x,\n\t\t\t\tfor='a b'\n\t\t\t)\n\t\t)\n\t)\n)",
@@ -1279,9 +1279,9 @@ public class Html5ComboTest extends ComboTest {
 				/* XmlT */		"<progress value='1'/>",
 				/* XmlR */		"<progress value='1'/>\n",
 				/* XmlNs */		"<progress value='1'/>",
-				/* Html */		"<progress value='1'/>",
-				/* HtmlT */		"<progress value='1'/>",
-				/* HtmlR */		"<progress value='1'/>\n",
+				/* Html */		"<progress value='1'></progress>",
+				/* HtmlT */		"<progress value='1'></progress>",
+				/* HtmlR */		"<progress value='1'></progress>\n",
 				/* Uon */		"(_type=progress,a=(value=1))",
 				/* UonT */		"(t=progress,a=(value=1))",
 				/* UonR */		"(\n\t_type=progress,\n\ta=(\n\t\tvalue=1\n\t)\n)",

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c32ae82a/juneau-core-test/src/test/java/org/apache/juneau/html/BasicHtmlTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/html/BasicHtmlTest.java b/juneau-core-test/src/test/java/org/apache/juneau/html/BasicHtmlTest.java
index b251eea..12a6707 100644
--- a/juneau-core-test/src/test/java/org/apache/juneau/html/BasicHtmlTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/html/BasicHtmlTest.java
@@ -1269,8 +1269,8 @@ public class BasicHtmlTest {
 			{
 				"BeanWithWhitespaceTextFields-1",
 				new BeanWithWhitespaceTextFields().init(null),
-				"<object/>",
-				"<object/>\n",
+				"<object></object>",
+				"<object></object>\n",
 			},
 			{
 				"BeanWithWhitespaceTextFields-2",
@@ -1299,8 +1299,8 @@ public class BasicHtmlTest {
 			{
 				"BeanWithWhitespaceTextPwsFields-1",
 				new BeanWithWhitespaceTextPwsFields().init(null),
-				"<object/>",
-				"<object/>\n",
+				"<object></object>",
+				"<object></object>\n",
 			},
 			{
 				"BeanWithWhitespaceTextPwsFields-2",
@@ -1329,14 +1329,14 @@ public class BasicHtmlTest {
 			{
 				"BeanWithWhitespaceMixedFields-1",
 				new BeanWithWhitespaceMixedFields().init(null),
-				"<object/>",
-				"<object/>\n",
+				"<object></object>",
+				"<object></object>\n",
 			},
 			{
 				"BeanWithWhitespaceMixedFields-2",
 				new BeanWithWhitespaceMixedFields().init(new String[0]),
-				"<object/>",
-				"<object/>\n",
+				"<object></object>",
+				"<object></object>\n",
 			},
 			{
 				"BeanWithWhitespaceMixedFields-3",
@@ -1365,14 +1365,14 @@ public class BasicHtmlTest {
 			{
 				"BeanWithWhitespaceMixedPwsFields-1",
 				new BeanWithWhitespaceMixedPwsFields().init(null),
-				"<object/>",
-				"<object/>\n",
+				"<object></object>",
+				"<object></object>\n",
 			},
 			{
 				"BeanWithWhitespaceMixedPwsFields-2",
 				new BeanWithWhitespaceMixedPwsFields().init(new String[0]),
-				"<object/>",
-				"<object/>\n",
+				"<object></object>",
+				"<object></object>\n",
 			},
 			{
 				"BeanWithWhitespaceMixedPwsFields-3",

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c32ae82a/juneau-core-test/src/test/java/org/apache/juneau/xml/InvalidXmlBeansTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/xml/InvalidXmlBeansTest.java b/juneau-core-test/src/test/java/org/apache/juneau/xml/InvalidXmlBeansTest.java
index 1bfec26..8d115a8 100644
--- a/juneau-core-test/src/test/java/org/apache/juneau/xml/InvalidXmlBeansTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/xml/InvalidXmlBeansTest.java
@@ -39,22 +39,22 @@ public class InvalidXmlBeansTest {
 			{
 				"BeanWithAttrFormat",
 				new BeanWithAttrFormat(),
-				"org.apache.juneau.xml.InvalidXmlBeansTest$BeanWithAttrFormat: Invalid format specified in @Xml annotation on bean: ATTR.  Must be one of the following: DEFAULT,ATTRS,ELEMENTS",
+				"org.apache.juneau.xml.InvalidXmlBeansTest$BeanWithAttrFormat: Invalid format specified in @Xml annotation on bean: ATTR.  Must be one of the following: DEFAULT,ATTRS,ELEMENTS,VOID",
 			},
 			{
 				"BeanWithElementFormat",
 				new BeanWithElementFormat(),
-				"org.apache.juneau.xml.InvalidXmlBeansTest$BeanWithElementFormat: Invalid format specified in @Xml annotation on bean: ELEMENT.  Must be one of the following: DEFAULT,ATTRS,ELEMENTS",
+				"org.apache.juneau.xml.InvalidXmlBeansTest$BeanWithElementFormat: Invalid format specified in @Xml annotation on bean: ELEMENT.  Must be one of the following: DEFAULT,ATTRS,ELEMENTS,VOID",
 			},
 			{
 				"BeanWithCollapsedFormat",
 				new BeanWithCollapsedFormat(),
-				"org.apache.juneau.xml.InvalidXmlBeansTest$BeanWithCollapsedFormat: Invalid format specified in @Xml annotation on bean: COLLAPSED.  Must be one of the following: DEFAULT,ATTRS,ELEMENTS",
+				"org.apache.juneau.xml.InvalidXmlBeansTest$BeanWithCollapsedFormat: Invalid format specified in @Xml annotation on bean: COLLAPSED.  Must be one of the following: DEFAULT,ATTRS,ELEMENTS,VOID",
 			},
 			{
 				"BeanWithMixedFormat",
 				new BeanWithMixedFormat(),
-				"org.apache.juneau.xml.InvalidXmlBeansTest$BeanWithMixedFormat: Invalid format specified in @Xml annotation on bean: MIXED.  Must be one of the following: DEFAULT,ATTRS,ELEMENTS",
+				"org.apache.juneau.xml.InvalidXmlBeansTest$BeanWithMixedFormat: Invalid format specified in @Xml annotation on bean: MIXED.  Must be one of the following: DEFAULT,ATTRS,ELEMENTS,VOID",
 			},
 			{
 				"BeanWithMultipleAttrs",

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c32ae82a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Area.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Area.java b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Area.java
index a096ff5..92e301e 100644
--- a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Area.java
+++ b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Area.java
@@ -21,7 +21,7 @@ import org.apache.juneau.annotation.*;
  * <p>
  */
 @Bean(typeName="area")
-public class Area extends HtmlElementEmpty {
+public class Area extends HtmlElementVoid {
 
 	/**
 	 * <a class="doclink" href="https://www.w3.org/TR/html5/embedded-content-0.html#attr-area-alt">alt</a> attribute.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c32ae82a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Base.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Base.java b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Base.java
index e001ce1..6a71088 100644
--- a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Base.java
+++ b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Base.java
@@ -21,7 +21,7 @@ import org.apache.juneau.annotation.*;
  * <p>
  */
 @Bean(typeName="base")
-public class Base extends HtmlElementEmpty {
+public class Base extends HtmlElementVoid {
 
 	/**
 	 * <a class="doclink" href="https://www.w3.org/TR/html5/document-metadata.html#attr-base-href">href</a> attribute.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c32ae82a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Br.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Br.java b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Br.java
index 5d449e5..e13f092 100644
--- a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Br.java
+++ b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Br.java
@@ -19,7 +19,7 @@ import org.apache.juneau.annotation.*;
  * <p>
  */
 @Bean(typeName="br")
-public class Br extends HtmlElementEmpty {
+public class Br extends HtmlElementVoid {
 
 	//--------------------------------------------------------------------------------
 	// Overridden methods

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c32ae82a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Col.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Col.java b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Col.java
index 2cdd46e..67a10b0 100644
--- a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Col.java
+++ b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Col.java
@@ -19,7 +19,7 @@ import org.apache.juneau.annotation.*;
  * <p>
  */
 @Bean(typeName="col")
-public class Col extends HtmlElementEmpty {
+public class Col extends HtmlElementVoid {
 
 	/**
 	 * <a class="doclink" href="https://www.w3.org/TR/html5/tabular-data.html#attr-col-span">span</a> attribute.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c32ae82a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Embed.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Embed.java b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Embed.java
index ce5916d..b1860f7 100644
--- a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Embed.java
+++ b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Embed.java
@@ -21,7 +21,7 @@ import org.apache.juneau.annotation.*;
  * <p>
  */
 @Bean(typeName="embed")
-public class Embed extends HtmlElementEmpty {
+public class Embed extends HtmlElementVoid {
 
 	/**
 	 * <a class="doclink" href="https://www.w3.org/TR/html5/embedded-content-0.html#attr-dim-height">height</a> attribute.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c32ae82a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Hr.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Hr.java b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Hr.java
index 26f2521..d87af17 100644
--- a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Hr.java
+++ b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Hr.java
@@ -19,7 +19,7 @@ import org.apache.juneau.annotation.*;
  * <p>
  */
 @Bean(typeName="hr")
-public class Hr extends HtmlElementEmpty {
+public class Hr extends HtmlElementVoid {
 
 	//--------------------------------------------------------------------------------
 	// Overridden methods

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c32ae82a/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementEmpty.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementEmpty.java b/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementEmpty.java
deleted file mode 100644
index 267d43f..0000000
--- a/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementEmpty.java
+++ /dev/null
@@ -1,19 +0,0 @@
-// ***************************************************************************************************************************
-// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
-// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
-// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
-// * with the License.  You may obtain a copy of the License at                                                              *
-// *                                                                                                                         *
-// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
-// *                                                                                                                         *
-// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
-// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
-// * specific language governing permissions and limitations under the License.                                              *
-// ***************************************************************************************************************************
-package org.apache.juneau.dto.html5;
-
-/**
- * A subclass of HTML elements that has no content.
- */
-public class HtmlElementEmpty extends HtmlElement {
-}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c32ae82a/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementVoid.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementVoid.java b/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementVoid.java
new file mode 100644
index 0000000..03ff3d3
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementVoid.java
@@ -0,0 +1,25 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.dto.html5;
+
+import org.apache.juneau.xml.annotation.*;
+import static org.apache.juneau.xml.annotation.XmlFormat.*;
+
+/**
+ * A subclass of HTML elements that have no content or end tags.
+ * <p>
+ * See <a href="https://www.w3.org/TR/html51/syntax.html#void-elements">void elements</a>
+ */
+@Xml(format=VOID)
+public class HtmlElementVoid extends HtmlElement {
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c32ae82a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Img.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Img.java b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Img.java
index 8b50045..d32b79b 100644
--- a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Img.java
+++ b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Img.java
@@ -20,7 +20,7 @@ import org.apache.juneau.annotation.*;
  * DTO for an HTML <a class="doclink" href="https://www.w3.org/TR/html5/embedded-content-0.html#the-img-element">&lt;img&gt;</a> element.
  */
 @Bean(typeName="img")
-public class Img extends HtmlElementEmpty {
+public class Img extends HtmlElementVoid {
 
 	/**
 	 * <a class="doclink" href="https://www.w3.org/TR/html5/embedded-content-0.html#attr-img-alt">alt</a> attribute.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c32ae82a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Input.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Input.java b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Input.java
index fbbfd9b..76c27fa 100644
--- a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Input.java
+++ b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Input.java
@@ -21,7 +21,7 @@ import org.apache.juneau.annotation.*;
  * <p>
  */
 @Bean(typeName="input")
-public class Input extends HtmlElementEmpty {
+public class Input extends HtmlElementVoid {
 
 	/**
 	 * <a class="doclink" href="https://www.w3.org/TR/html5/forms.html#attr-input-accept">accept</a> attribute.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c32ae82a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Keygen.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Keygen.java b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Keygen.java
index 1ad6617..17bb0c4 100644
--- a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Keygen.java
+++ b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Keygen.java
@@ -19,7 +19,7 @@ import org.apache.juneau.annotation.*;
  * <p>
  */
 @Bean(typeName="keygen")
-public class Keygen extends HtmlElementEmpty {
+public class Keygen extends HtmlElementVoid {
 
 	/**
 	 * <a class="doclink" href="https://www.w3.org/TR/html5/forms.html#attr-fe-autofocus">autofocus</a> attribute.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c32ae82a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Link.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Link.java b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Link.java
index e25d90c..6826288 100644
--- a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Link.java
+++ b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Link.java
@@ -21,7 +21,7 @@ import org.apache.juneau.annotation.*;
  * <p>
  */
 @Bean(typeName="link")
-public class Link extends HtmlElementEmpty {
+public class Link extends HtmlElementVoid {
 
 	/**
 	 * <a class="doclink" href="https://www.w3.org/TR/html5/document-metadata.html#attr-link-crossorigin">crossorigin</a> attribute.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c32ae82a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Meta.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Meta.java b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Meta.java
index fd98fa7..acca749 100644
--- a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Meta.java
+++ b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Meta.java
@@ -19,7 +19,7 @@ import org.apache.juneau.annotation.*;
  * <p>
  */
 @Bean(typeName="meta")
-public class Meta extends HtmlElementEmpty {
+public class Meta extends HtmlElementVoid {
 
 	/**
 	 * <a class="doclink" href="https://www.w3.org/TR/html5/document-metadata.html#attr-meta-charset">charset</a> attribute.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c32ae82a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Param.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Param.java b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Param.java
index 04fe149..88c952a 100644
--- a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Param.java
+++ b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Param.java
@@ -19,7 +19,7 @@ import org.apache.juneau.annotation.*;
  * <p>
  */
 @Bean(typeName="param")
-public class Param extends HtmlElementEmpty {
+public class Param extends HtmlElementVoid {
 
 	/**
 	 * <a class="doclink" href="https://www.w3.org/TR/html5/embedded-content-0.html#attr-param-name">name</a> attribute.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c32ae82a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Source.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Source.java b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Source.java
index 59f9996..0c4c5fb 100644
--- a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Source.java
+++ b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Source.java
@@ -21,7 +21,7 @@ import org.apache.juneau.annotation.*;
  * <p>
  */
 @Bean(typeName="source")
-public class Source extends HtmlElementEmpty {
+public class Source extends HtmlElementVoid {
 
 	/**
 	 * <a class="doclink" href="https://www.w3.org/TR/html5/embedded-content-0.html#attr-source-src">src</a> attribute.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c32ae82a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Track.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Track.java b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Track.java
index e3f4728..fb52d84 100644
--- a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Track.java
+++ b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Track.java
@@ -21,7 +21,7 @@ import org.apache.juneau.annotation.*;
  * <p>
  */
 @Bean(typeName="track")
-public class Track extends HtmlElementEmpty {
+public class Track extends HtmlElementVoid {
 
 	/**
 	 * <a class="doclink" href="https://www.w3.org/TR/html5/embedded-content-0.html#attr-track-default">default</a> attribute.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c32ae82a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Wbr.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Wbr.java b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Wbr.java
index 8476223..a8ed623 100644
--- a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Wbr.java
+++ b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Wbr.java
@@ -19,7 +19,7 @@ import org.apache.juneau.annotation.*;
  * <p>
  */
 @Bean(typeName="wbr")
-public class Wbr extends HtmlElementEmpty {
+public class Wbr extends HtmlElementVoid {
 
 	//--------------------------------------------------------------------------------
 	// Overridden methods

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c32ae82a/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java
index ad573c8..992067e 100644
--- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java
@@ -181,4 +181,9 @@ public class HtmlSerializerSession extends XmlSerializerSession {
 	public final boolean isAddBeanTypeProperties() {
 		return addBeanTypeProperties;
 	}
+
+	@Override /* XmlSerializer */
+	public boolean isHtmlMode() {
+		return true;
+	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c32ae82a/juneau-core/src/main/java/org/apache/juneau/xml/XmlBeanMeta.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/XmlBeanMeta.java b/juneau-core/src/main/java/org/apache/juneau/xml/XmlBeanMeta.java
index 4135272..df2f994 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/XmlBeanMeta.java
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlBeanMeta.java
@@ -49,8 +49,12 @@ public class XmlBeanMeta extends BeanMetaExtended {
 				defaultFormat = XmlFormat.ATTR;
 			else if (xf.isOneOf(ELEMENTS, DEFAULT))
 				defaultFormat = ELEMENT;
+			else if (xf == VOID) {
+				_contentFormat = VOID;
+				defaultFormat = VOID;
+			}
 			else
-				throw new BeanRuntimeException(c, "Invalid format specified in @Xml annotation on bean: {0}.  Must be one of the following: DEFAULT,ATTRS,ELEMENTS", xml.format());
+				throw new BeanRuntimeException(c, "Invalid format specified in @Xml annotation on bean: {0}.  Must be one of the following: DEFAULT,ATTRS,ELEMENTS,VOID", xml.format());
 		}
 
 		Map<String,BeanPropertyMeta> _attrs = new LinkedHashMap<String,BeanPropertyMeta>();
@@ -106,7 +110,7 @@ public class XmlBeanMeta extends BeanMetaExtended {
 		contentFormat = _contentFormat;
 
 		// Do some validation.
-		if (contentProperty != null) {
+		if (contentProperty != null || contentFormat == XmlFormat.VOID) {
 			if (! elements.isEmpty())
 				throw new BeanRuntimeException(c, "{0} and ELEMENT properties found on the same bean.  These cannot be mixed.", contentFormat);
 			if (! collapsedProperties.isEmpty())
@@ -221,6 +225,7 @@ public class XmlBeanMeta extends BeanMetaExtended {
 	 * 	<li>{@link XmlFormat#TEXT}
 	 * 	<li>{@link XmlFormat#TEXT_PWS}
 	 * 	<li>{@link XmlFormat#XMLTEXT}
+	 * 	<li>{@link XmlFormat#VOID}
 	 * 	<li><jk>null</jk>
 	 * </ul>
 	 *

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c32ae82a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializer.java b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializer.java
index 0f22162..bb4f6bc 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializer.java
@@ -495,8 +495,14 @@ public class XmlSerializer extends WriterSerializer {
 
 		// Render the end tag.
 		if (! isCollapsed) {
-			if (o == null || rc == CR_EMPTY)
+			if (rc == CR_EMPTY) {
+				if (session.isHtmlMode())
+					out.append('>').eTag(elementNs, en, encodeEn);
+				else
+					out.append('/').append('>');
+			} else if (rc == CR_VOID || o == null) {
 				out.append('/').append('>');
+			}
 			else
 				out.i(cr && rc != CR_MIXED ? indent : 0).eTag(elementNs, en, encodeEn);
 			if (! isMixed)
@@ -599,7 +605,10 @@ public class XmlSerializer extends WriterSerializer {
 			}
 		}
 
-		boolean hasContent = false, preserveWhitespace = false;
+		boolean
+			hasContent = false,
+			preserveWhitespace = false,
+			isVoidElement = xbm.getContentFormat() == VOID;
 
 		for (BeanPropertyValue p : lp) {
 			BeanPropertyMeta pMeta = p.getMeta();
@@ -639,7 +648,7 @@ public class XmlSerializer extends WriterSerializer {
 			}
 		}
 		if (! hasContent)
-			return (hasChildren ? CR_ELEMENTS : CR_EMPTY);
+			return (hasChildren ? CR_ELEMENTS : isVoidElement ? CR_VOID : CR_EMPTY);
 		out.append('>').nlIf(! isMixed);
 
 		// Serialize XML content.
@@ -737,9 +746,10 @@ public class XmlSerializer extends WriterSerializer {
 	 * Identifies what the contents were of a serialized bean.
 	 */
 	static enum ContentResult {
-		CR_EMPTY,    // No content...append "/>" to the start tag.
-		CR_MIXED,    // Mixed content...don't add whitespace.
-		CR_ELEMENTS  // Elements...use normal whitespace rules.
+		CR_VOID,      // No content...append "/>" to the start tag.
+		CR_EMPTY,     // No content...append "/>" to the start tag if XML, "/></end>" if HTML.
+		CR_MIXED,     // Mixed content...don't add whitespace.
+		CR_ELEMENTS   // Elements...use normal whitespace rules.
 	}
 
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c32ae82a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java
index c806704..223f75b 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java
@@ -179,6 +179,19 @@ public class XmlSerializerSession extends SerializerSession {
 		return xsNamespace;
 	}
 
+	/**
+	 * Returns <jk>true</jk> if we're serializing HTML.
+	 * <p>
+	 * The difference in behavior is how empty non-void elements are handled.
+	 * The XML serializer will produce a collapsed tag, whereas the HTML serializer
+	 * will produce a start and end tag.
+	 *
+	 * @return <jk>true</jk> if we're generating HTML.
+	 */
+	public boolean isHtmlMode() {
+		return false;
+	}
+
 	@Override /* SerializerSession */
 	public XmlWriter getWriter() throws Exception {
 		Object output = getOutput();

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c32ae82a/juneau-core/src/main/java/org/apache/juneau/xml/annotation/XmlFormat.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/annotation/XmlFormat.java b/juneau-core/src/main/java/org/apache/juneau/xml/annotation/XmlFormat.java
index 905cc40..388dc67 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/annotation/XmlFormat.java
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/annotation/XmlFormat.java
@@ -118,7 +118,21 @@ public enum XmlFormat {
 	 * <p>
 	 * Can only be applied to properties (methods/fields) of type collection or array, or collection classes.
 	 */
-	COLLAPSED;
+	COLLAPSED,
+
+	/**
+	 * Identifies a void element.
+	 * <p>
+	 * Only applicable for bean classes.
+	 * <p>
+	 * Identifies an element that never contains content.
+	 * <p>
+	 * The main difference in behavior is how non-void empty elements are handled
+	 * in the HTML serializer.  
+	 * Void elements are serialized as collapsed nodes (e.g. <js>"&lt;br/&gt;"</js>)
+	 * whereas non-void empty elements are serialized with an end tag (e.g. "&lt;p&gt;&lt;/p&gt;").
+	 */
+	VOID;
 
 	/**
 	 * Returns <jk>true</jk> if this format is one of those specified.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c32ae82a/juneau-core/src/main/javadoc/overview.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/javadoc/overview.html b/juneau-core/src/main/javadoc/overview.html
index 3ce43ed..0b80cc3 100644
--- a/juneau-core/src/main/javadoc/overview.html
+++ b/juneau-core/src/main/javadoc/overview.html
@@ -5600,6 +5600,8 @@
 				<li>{@link org.apache.juneau.xml.XmlSerializerContext#XML_addBeanTypeProperties}
 				<li>{@link org.apache.juneau.jena.RdfSerializerContext#RDF_addBeanTypeProperties}
 			</ul>
+			<li>New {@link org.apache.juneau.xml.annotation.XmlFormat#VOID} format to identify HTML void elements.
+			<li>More-correct handling of empty non-void elements in HTML serializer.
 			<li>Improvements to Swagger support.
 			<ul>
 				<li>New {@link org.apache.juneau.dto.swagger.SwaggerBuilder} class.