Index: src/test/groovy/xml/MarkupBuilderTest.groovy
===================================================================
--- src/test/groovy/xml/MarkupBuilderTest.groovy	(revision 4983)
+++ src/test/groovy/xml/MarkupBuilderTest.groovy	(working copy)
@@ -37,6 +37,14 @@
   <element attr='value 1 &amp; 2'>chars: &amp; &lt; &gt; " in middle</element>
   <greaterthan>&gt;</greaterthan>
   <emptyElement />
+  <null />
+  <nullAttribute />
+  <emptyWithAttributes attr1='set' />
+  <emptyAttribute t1='' />
+  <parent key='value'>
+    <label for='usernameId'>Username: </label>
+    <input name='test' id='1' />
+  </parent>
 </chars>'''
 
         // Generate the markup.
@@ -48,6 +56,14 @@
             element(attr: "value 1 & 2", "chars: & < > \" in middle")
             greaterthan(">")
             emptyElement()
+            'null'(null)
+            nullAttribute(t1:null)
+            emptyWithAttributes(attr1:'set')
+            emptyAttribute(t1:'')
+            parent(key:'value'){
+                label(for:'usernameId', 'Username: ')
+                input(id:1, name:'test')
+            }
         }
 
         // Compare the MarkupBuilder generated XML with the 'expectedXml'
Index: src/main/groovy/xml/MarkupBuilder.java
===================================================================
--- src/main/groovy/xml/MarkupBuilder.java	(revision 4983)
+++ src/main/groovy/xml/MarkupBuilder.java	(working copy)
@@ -116,27 +116,34 @@
     }
 
     protected Object createNode(Object name, Object value) {
-        toState(2, name);
-        this.nodeIsEmpty = false;
-        out.print(">");
-        out.print(escapeElementContent(value.toString()));
-        return name;
+        if (value == null){
+            return createNode(name);
+        }
+        else{
+            toState(2, name);
+            this.nodeIsEmpty = false;
+            out.print(">");
+            out.print(escapeElementContent(value.toString()));
+            return name;
+        }
     }
 
     protected Object createNode(Object name, Map attributes, Object value) {
         toState(1, name);
         for (Iterator iter = attributes.entrySet().iterator(); iter.hasNext();) {
             Map.Entry entry = (Map.Entry) iter.next();
-            out.print(" ");
 
-            // Output the attribute name,
-            print(entry.getKey().toString());
-
-            // Output the attribute value within quotes. Use whichever
-            // type of quotes are currently configured.
-            out.print(this.useDoubleQuotes ? "=\"" : "='");
-            print(escapeAttributeValue(entry.getValue().toString()));
-            out.print(this.useDoubleQuotes ? "\"" : "'");
+            if (entry.getValue() != null){
+                // Output the attribute name,
+                out.print(" ");
+                print(entry.getKey().toString());
+    
+                // Output the attribute value within quotes. Use whichever
+                // type of quotes are currently configured.
+                out.print(this.useDoubleQuotes ? "=\"" : "='");
+                print(escapeAttributeValue(entry.getValue().toString()));
+                out.print(this.useDoubleQuotes ? "\"" : "'");
+            }
         }
 
         if (value != null) {

