http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/4fb01038/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 6836fbc..cf5f007 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
@@ -15,6 +15,8 @@ package org.apache.juneau.xml;
 import static org.apache.juneau.serializer.SerializerContext.*;
 import static org.apache.juneau.xml.XmlSerializerContext.*;
 import static org.apache.juneau.xml.annotation.XmlFormat.*;
+import static org.apache.juneau.xml.XmlSerializer.ContentResult.*;
+import static org.apache.juneau.xml.XmlSerializer.JsonType.*;
 
 import java.lang.reflect.*;
 import java.util.*;
@@ -81,7 +83,6 @@ import org.apache.juneau.xml.annotation.*;
  * <p>
  *     An additional "add-json-properties" mode is also provided to prevent 
loss of JSON data types...
  * <p class='bcode'>
- *     <xt>&lt;object&gt;</xt>
  *             <xt>&lt;name</xt> 
<xa>_type</xa>=<xs>'string'</xs><xt>&gt;</xt>John Smith<xt>&lt;/name&gt;</xt>
  *             <xt>&lt;address</xt> 
<xa>_type</xa>=<xs>'object'</xs><xt>&gt;</xt>
  *                     <xt>&lt;streetAddress</xt> 
<xa>_type</xa>=<xs>'string'</xs><xt>&gt;</xt>21 2nd 
Street<xt>&lt;/streetAddress&gt;</xt>
@@ -118,38 +119,29 @@ import org.apache.juneau.xml.annotation.*;
  * <ul class='spaced-list'>
  *     <li>{@link Sq} - Default serializer, single quotes.
  *     <li>{@link SqReadable} - Default serializer, single quotes, whitespace 
added.
- *     <li>{@link XmlJson} - Default serializer with JSON attribute tags.
- *     <li>{@link XmlJsonSq} - Default serializer with JSON attribute tags, 
single quotes.
  * </ul>
  */
 @SuppressWarnings({ "rawtypes", "unchecked" })
 @Produces("text/xml")
 public class XmlSerializer extends WriterSerializer {
 
-       /** Default serializer, all default settings. */
+       /** Default serializer without namespaces. */
        public static final XmlSerializer DEFAULT = new XmlSerializer().lock();
 
-       /** Default serializer, single quotes. */
+       /** Default serializer without namespaces, with single quotes. */
        public static final XmlSerializer DEFAULT_SQ = new 
XmlSerializer.Sq().lock();
 
-       /** Default serializer, single quotes, whitespace added. */
+       /** Default serializer without namespaces, with single quotes, 
whitespace added. */
        public static final XmlSerializer DEFAULT_SQ_READABLE = new 
XmlSerializer.SqReadable().lock();
 
-       /** Default serializer with JSON attribute tags. */
-       public static final XmlSerializer DEFAULT_XMLJSON = new 
XmlSerializer.XmlJson().lock();
-
-       /** Default serializer with JSON attribute tags, single quotes. */
-       public static final XmlSerializer DEFAULT_XMLJSON_SQ = new 
XmlSerializer.XmlJsonSq().lock();
-
-       /** Default serializer without namespaces. */
-       public static final XmlSerializer DEFAULT_SIMPLE = new 
XmlSerializer.Simple().lock();
-
-       /** Default serializer without namespaces, with single quotes. */
-       public static final XmlSerializer DEFAULT_SIMPLE_SQ = new 
XmlSerializer.SimpleSq().lock();
+       /** Default serializer, all default settings. */
+       public static final XmlSerializer DEFAULT_NS = new 
XmlSerializer.Ns().lock();
 
-       /** Default serializer without namespaces, with JSON attribute tags and 
single quotes. */
-       public static final XmlSerializer DEFAULT_SIMPLE_XMLJSON_SQ = new 
XmlSerializer.SimpleXmlJsonSq().lock();
+       /** Default serializer, single quotes. */
+       public static final XmlSerializer DEFAULT_NS_SQ = new 
XmlSerializer.NsSq().lock();
 
+       /** Default serializer, single quotes, whitespace added. */
+       public static final XmlSerializer DEFAULT_NS_SQ_READABLE = new 
XmlSerializer.NsSqReadable().lock();
 
        /** Default serializer, single quotes. */
        public static class Sq extends XmlSerializer {
@@ -167,45 +159,28 @@ public class XmlSerializer extends WriterSerializer {
                }
        }
 
-       /** Default serializer with JSON attribute tags. */
-       @Produces(value="text/xml+json",contentType="text/xml")
-       public static class XmlJson extends XmlSerializer {
-               /** Constructor */
-               public XmlJson() {
-                       setProperty(XML_addJsonTypeAttrs, true);
-               }
-       }
-
-       /** Default serializer with JSON attribute tags, single quotes. */
-       public static class XmlJsonSq extends XmlJson {
-               /** Constructor */
-               public XmlJsonSq() {
-                       setProperty(SERIALIZER_quoteChar, '\'');
-               }
-       }
-
        /** Default serializer without namespaces. */
        @Produces(value="text/xml+simple",contentType="text/xml")
-       public static class Simple extends XmlSerializer {
+       public static class Ns extends XmlSerializer {
                /** Constructor */
-               public Simple() {
-                       setProperty(XML_enableNamespaces, false);
+               public Ns() {
+                       setProperty(XML_enableNamespaces, true);
                }
        }
 
        /** Default serializer without namespaces, single quotes. */
-       public static class SimpleSq extends Simple {
+       public static class NsSq extends Ns {
                /** Constructor */
-               public SimpleSq() {
+               public NsSq() {
                        setProperty(SERIALIZER_quoteChar, '\'');
                }
        }
 
-       /** Default serializer with JSON attribute tags, single quotes. */
-       public static class SimpleXmlJsonSq extends SimpleSq {
+       /** Default serializer without namespaces, single quotes, with 
whitespace. */
+       public static class NsSqReadable extends NsSq {
                /** Constructor */
-               public SimpleXmlJsonSq() {
-                       setProperty(XML_addJsonTypeAttrs, true);
+               public NsSqReadable() {
+                       setProperty(SERIALIZER_useIndentation, true);
                }
        }
 
@@ -303,18 +278,27 @@ public class XmlSerializer extends WriterSerializer {
         * @param elementNamespace The namespace of the element.
         * @param addNamespaceUris Flag indicating that namespace URIs need to 
be added.
         * @param format The format to serialize the output to.
+        * @param isMixed We're serializing mixed content, so don't use 
whitespace.
         * @param pMeta The bean property metadata if this is a bean property 
being serialized.
         * @return The same writer passed in so that calls to the writer can be 
chained.
         * @throws Exception If a problem occurred trying to convert the output.
         */
-       protected XmlWriter serializeAnything(XmlSerializerSession session, 
XmlWriter out, Object o,
-                       ClassMeta eType, String elementName, Namespace 
elementNamespace, boolean addNamespaceUris,
-                       XmlFormat format, BeanPropertyMeta pMeta) throws 
Exception {
-
-               String ts = null;              // The type string (e.g. <type> 
or <x x='type'>
-               int indent = session.indent;       // Current indentation
+       protected XmlWriter serializeAnything(
+                       XmlSerializerSession session,
+                       XmlWriter out,
+                       Object o,
+                       ClassMeta eType,
+                       String elementName,
+                       Namespace elementNamespace,
+                       boolean addNamespaceUris,
+                       XmlFormat format,
+                       boolean isMixed,
+                       BeanPropertyMeta pMeta) throws Exception {
+
+               JsonType type = null;              // The type string (e.g. 
<type> or <x x='type'>
+               int indent = isMixed ? 0 : session.indent;       // Current 
indentation
                ClassMeta<?> aType = null;     // The actual type
-               ClassMeta<?> wType = null;     // The wrapped type
+               ClassMeta<?> wType = null;     // The wrapped type (delegate)
                ClassMeta<?> sType = object(); // The serialized type
 
                aType = session.push(elementName, o, eType);
@@ -332,7 +316,7 @@ public class XmlSerializer extends WriterSerializer {
 
                        if (aType.isDelegate()) {
                                wType = aType;
-                               aType = ((Delegate)o).getClassMeta();
+                               eType = aType = ((Delegate)o).getClassMeta();
                        }
 
                        sType = aType.getSerializedClassMeta();
@@ -351,12 +335,22 @@ public class XmlSerializer extends WriterSerializer {
                        sType = eType.getSerializedClassMeta();
                }
 
-               String typeName = null;
-               if (session.isAddBeanTypeProperties()) {
-                       if (o != null && ! eType.equals(aType))
-                               typeName = aType.getDictionaryName();
+               // Does the actual type match the expected type?
+               boolean isExpectedType = true;
+               if (o == null || ! eType.same(aType)) {
+                       if (eType.isNumber())
+                               isExpectedType = aType.isNumber();
+                       else if (eType.isMap())
+                               isExpectedType = aType.isMap();
+                       else if (eType.isCollection())
+                               isExpectedType = aType.isCollection();
+                       else
+                               isExpectedType = false;
                }
 
+               String resolvedDictionaryName = isExpectedType ? null : 
aType.getResolvedDictionaryName();
+               String dictionaryName = aType.getDictionaryName();
+
                // char '\0' is interpreted as null.
                if (o != null && sType.isChar() && ((Character)o).charValue() 
== 0)
                        o = null;
@@ -364,33 +358,32 @@ public class XmlSerializer extends WriterSerializer {
                boolean isCollapsed = false;            // If 'true', this is a 
collection and we're not rendering the outer element.
 
                // Get the JSON type string.
-               if (sType.isCharSequence() || sType.isChar())
-                       ts = "string";
-               else if (sType.isNumber())
-                       ts = "number";
-               else if (sType.isBoolean())
-                       ts = "boolean";
-               else if (sType.isMap() || sType.isBean() || 
sType.hasToObjectMapMethod()) {
-                       isCollapsed = 
sType.getExtendedMeta(XmlClassMeta.class).getFormat() == XmlFormat.COLLAPSED;
-                       ts = "object";
-               }
-               else if (sType.isCollection() || sType.isArray()) {
+               if (o == null) {
+                       type = NULL;
+               } else if (sType.isCharSequence() || sType.isChar()) {
+                       type = STRING;
+               } else if (sType.isNumber()) {
+                       type = NUMBER;
+               } else if (sType.isBoolean()) {
+                       type = BOOLEAN;
+               } else if (sType.isMapOrBean() || sType.hasToObjectMapMethod()) 
{
+                       isCollapsed = 
sType.getExtendedMeta(XmlClassMeta.class).getFormat() == COLLAPSED;
+                       type = OBJECT;
+               } else if (sType.isCollectionOrArray()) {
                        isCollapsed = (format == COLLAPSED && ! 
addNamespaceUris);
-                       ts = "array";
+                       type = ARRAY;
+               } else {
+                       type = STRING;
                }
-               else
-                       ts = "string";
 
-               // Is there a name associated with this bean?
-               if (elementName == null)
-                       elementName = sType.getDictionaryName();
+               if (format.isOneOf(MIXED,TEXT,XMLTEXT) && 
type.isOneOf(NULL,STRING,NUMBER,BOOLEAN))
+                       isCollapsed = true;
 
-               // If the value is null then it's either going to be <null/> or 
<XmlSerializer nil='true'/>
-               // depending on whether the element has a name.
-               boolean isNullTag = (elementName == null && o == null);
-
-               if (isNullTag)
-                       ts = "null";
+               // Is there a name associated with this bean?
+               if (elementName == null && dictionaryName != null) {
+                       elementName = dictionaryName;
+                       isExpectedType = true;
+               }
 
                if (session.isEnableNamespaces()) {
                        if (elementNamespace == null)
@@ -406,14 +399,17 @@ public class XmlSerializer extends WriterSerializer {
                }
 
                // Do we need a carriage return after the start tag?
-               boolean cr = o != null && (sType.isMap() || 
sType.isCollection() || sType.isArray() || sType.isBean() || 
sType.hasToObjectMapMethod());
+               boolean cr = o != null && (sType.isMapOrBean() || 
sType.isCollectionOrArray() || sType.hasToObjectMapMethod()) && ! isMixed;
 
-               String en = (elementName == null ? ts : elementName);
+               String en = elementName;
+               if (en == null) {
+                       en = type.toString();
+                       type = null;
+               }
                boolean encodeEn = elementName != null;
                String ns = (elementNamespace == null ? null : 
elementNamespace.name);
-               String xsi = null, dns = null, elementNs = null;
+               String dns = null, elementNs = null;
                if (session.isEnableNamespaces()) {
-                       xsi = session.getXsiNamespace().name;
                        dns = elementName == null && 
session.getDefaultNamespace() != null ? session.getDefaultNamespace().name : 
null;
                        elementNs = elementName == null ? dns : ns;
                        if (elementName == null)
@@ -428,85 +424,90 @@ public class XmlSerializer extends WriterSerializer {
 
                                for (Namespace n : session.getNamespaces())
                                        out.attr("xmlns", n.getName(), 
n.getUri());
-
-                               Namespace xsiNs = session.getXsiNamespace();
-                               if (xsiNs != null)
-                                       out.attr("xmlns", xsiNs.name, 
xsiNs.uri);
                        }
-                       if (typeName == null && elementName != null && 
session.isAddJsonTypeAttrs() && (session.isAddJsonStringTypeAttrs() || ! 
ts.equals("string")))
-                               typeName = ts;
-                       if (typeName != null && ! typeName.equals(elementName))
-                               out.attr(dns, 
session.getBeanTypePropertyName(), typeName);
+                       if (! isExpectedType) {
+                               if (resolvedDictionaryName != null)
+                                       out.attr(dns, 
session.getBeanTypePropertyName(), resolvedDictionaryName);
+                               else if (type != null && type != STRING)
+                                       out.attr(dns, 
session.getBeanTypePropertyName(), type);
+                       }
                        if (o == null) {
-                               if (! isNullTag)
-                                       out.attr(xsi, "nil", "true");
                                if ((sType.isBoolean() || sType.isNumber()) && 
! sType.isNullable())
                                        o = sType.getPrimitiveDefault();
                        }
 
-                       if (o != null && !(sType.isMap() || sType.isBean() || 
sType.hasToObjectMapMethod()))
+                       if (o != null && ! (sType.isMapOrBean() || 
sType.hasToObjectMapMethod()))
                                out.append('>');
 
-                       if (cr && !(sType.isMap() || sType.isBean() || 
sType.hasToObjectMapMethod()))
+                       if (cr && ! (sType.isMapOrBean() || 
sType.hasToObjectMapMethod()))
                                out.nl();
                }
 
-               boolean hasChildren = true;
+               ContentResult rc = CR_ELEMENTS;
 
                // Render the tag contents.
                if (o != null) {
-                       if (sType.isUri() || (pMeta != null && pMeta.isUri()))
+                       if (sType.isUri() || (pMeta != null && pMeta.isUri())) {
                                out.appendUri(o);
-                       else if (sType.isCharSequence() || sType.isChar())
-                               out.encodeText(session.trim(o));
-                       else if (sType.isNumber() || sType.isBoolean())
+                       } else if (sType.isCharSequence() || sType.isChar()) {
+                               if (format == XMLTEXT)
+                                       out.append(o);
+                               else
+                                       out.encodeText(session.trim(o));
+                       } else if (sType.isNumber() || sType.isBoolean()) {
                                out.append(o);
-                       else if (sType.isMap() || (wType != null && 
wType.isMap())) {
+                       } else if (sType.isMap() || (wType != null && 
wType.isMap())) {
                                if (o instanceof BeanMap)
-                                       hasChildren = serializeBeanMap(session, 
out, (BeanMap)o, elementNamespace, isCollapsed);
+                                       rc = serializeBeanMap(session, out, 
(BeanMap)o, elementNamespace, isCollapsed, isMixed);
                                else
-                                       hasChildren = serializeMap(session, 
out, (Map)o, sType);
-                       }
-                       else if (sType.hasToObjectMapMethod())
-                               hasChildren = serializeMap(session, out, 
sType.toObjectMap(o), sType);
-                       else if (sType.isBean())
-                               hasChildren = serializeBeanMap(session, out, 
session.toBeanMap(o), elementNamespace, isCollapsed);
-                       else if (sType.isCollection() || (wType != null && 
wType.isCollection())) {
+                                       rc = serializeMap(session, out, (Map)o, 
sType, eType.getKeyType(), eType.getValueType(), isMixed);
+                       } else if (sType.hasToObjectMapMethod()) {
+                               rc = serializeMap(session, out, 
sType.toObjectMap(o), sType, null, null, isMixed);
+                       } else if (sType.isBean()) {
+                               rc = serializeBeanMap(session, out, 
session.toBeanMap(o), elementNamespace, isCollapsed, isMixed);
+                       } else if (sType.isCollection() || (wType != null && 
wType.isCollection())) {
                                if (isCollapsed)
                                        session.indent--;
-                               serializeCollection(session, out, 
(Collection)o, sType, pMeta);
+                               serializeCollection(session, out, o, sType, 
eType, pMeta, isMixed);
                                if (isCollapsed)
                                        session.indent++;
-                       }
-                       else if (sType.isArray()) {
+                       } else if (sType.isArray()) {
                                if (isCollapsed)
                                        session.indent--;
-                               serializeCollection(session, out, 
toList(sType.getInnerClass(), o), sType, pMeta);
+                               if (resolvedDictionaryName != null)
+                                       eType = aType;
+                               serializeCollection(session, out, o, sType, 
eType, pMeta, isMixed);
                                if (isCollapsed)
                                        session.indent++;
+                       } else {
+                               if (format == XMLTEXT)
+                                       out.append(session.toString(o));
+                               else
+                                       out.encodeText(session.toString(o));
                        }
-                       else
-                               out.encodeText(session.toString(o));
                }
 
                session.pop();
 
                // Render the end tag.
                if (! isCollapsed) {
-                       if (o == null || ! hasChildren)
-                               out.append('/').append('>').nl();
+                       if (o == null || rc == CR_EMPTY)
+                               out.append('/').append('>');
                        else
-                               out.i(cr ? indent : 0).eTag(elementNs, en, 
encodeEn).nl();
+                               out.i(cr && rc != CR_MIXED ? indent : 
0).eTag(elementNs, en, encodeEn);
+                       if (! isMixed)
+                               out.nl();
                }
 
                return out;
        }
 
-       private boolean serializeMap(XmlSerializerSession session, XmlWriter 
out, Map m, ClassMeta<?> type) throws Exception {
+       private ContentResult serializeMap(XmlSerializerSession session, 
XmlWriter out, Map m, ClassMeta<?> sType, ClassMeta<?> eKeyType, ClassMeta<?> 
eValueType, boolean isMixed) throws Exception {
 
                m = session.sort(m);
 
-               ClassMeta<?> keyType = type.getKeyType(), valueType = 
type.getValueType();
+               ClassMeta<?> keyType = eKeyType == null ? sType.getKeyType() : 
eKeyType;
+               ClassMeta<?> valueType = eValueType == null ? 
sType.getValueType() : eValueType;
 
                boolean hasChildren = false;
                for (Iterator i = m.entrySet().iterator(); i.hasNext();) {
@@ -525,23 +526,36 @@ public class XmlSerializer extends WriterSerializer {
 
                        if (! hasChildren) {
                                hasChildren = true;
-                               out.append('>').nl();
+                               out.append('>').nlIf(! isMixed);
                        }
-                       serializeAnything(session, out, value, valueType, 
session.toString(k), null, false, NORMAL, null);
+                       serializeAnything(session, out, value, valueType, 
session.toString(k), null, false, XmlFormat.DEFAULT, isMixed, null);
                }
-               return hasChildren;
+               return hasChildren ? CR_ELEMENTS : CR_EMPTY;
        }
 
-       private boolean serializeBeanMap(XmlSerializerSession session, 
XmlWriter out, BeanMap<?> m, Namespace elementNs, boolean isCollapsed) throws 
Exception {
+       private ContentResult serializeBeanMap(XmlSerializerSession session, 
XmlWriter out, BeanMap<?> m, Namespace elementNs, boolean isCollapsed, boolean 
isMixed) throws Exception {
                boolean hasChildren = false;
                BeanMeta<?> bm = m.getMeta();
 
                List<BeanPropertyValue> lp = m.getValues(session.isTrimNulls());
 
-               Map<String,BeanPropertyMeta> xmlAttrs = 
bm.getExtendedMeta(XmlBeanMeta.class).getXmlAttrProperties();
+               XmlBeanMeta xbm = bm.getExtendedMeta(XmlBeanMeta.class);
+
+               Set<String>
+                       attrs = xbm.getAttrPropertyNames(),
+                       elements = xbm.getElementPropertyNames(),
+                       collapsedElements = xbm.getCollapsedPropertyNames();
+               String
+                       attrsProperty = xbm.getAttrsPropertyName(),
+                       contentProperty = xbm.getContentPropertyName();
+
+               XmlFormat cf = null;
+
                Object content = null;
+               ClassMeta<?> contentType = null;
                for (BeanPropertyValue p : lp) {
-                       if (xmlAttrs.containsKey(p.getName())) {
+                       String n = p.getName();
+                       if (attrs.contains(n) || n.equals(attrsProperty)) {
                                BeanPropertyMeta pMeta = p.getMeta();
                                ClassMeta<?> cMeta = p.getClassMeta();
 
@@ -556,10 +570,28 @@ public class XmlSerializer extends WriterSerializer {
 
                                Namespace ns = (session.isEnableNamespaces() && 
pMeta.getExtendedMeta(XmlBeanPropertyMeta.class).getNamespace() != elementNs ? 
pMeta.getExtendedMeta(XmlBeanPropertyMeta.class).getNamespace() : null);
 
-                               if (pMeta.isUri())
+                               if (pMeta.isUri()) {
                                        out.attrUri(ns, key, value);
-                               else
+                               } else if (n.equals(attrsProperty)) {
+                                       if (value instanceof BeanMap) {
+                                               BeanMap<?> bm2 = (BeanMap)value;
+                                               for (BeanPropertyValue p2 : 
bm2.getValues(true)) {
+                                                       String key2 = 
p2.getName();
+                                                       Object value2 = 
p2.getValue();
+                                                       Throwable t2 = 
p2.getThrown();
+                                                       if (t2 != null)
+                                                               
session.addBeanGetterWarning(pMeta, t);
+                                                       out.attr(ns, key2, 
value2);
+                                               }
+                                       } else /* Map */ {
+                                               Map m2 = (Map)value;
+                                               for (Map.Entry e : 
(Set<Map.Entry>)(m2.entrySet())) {
+                                                       out.attr(ns, 
session.toString(e.getKey()), e.getValue());
+                                               }
+                                       }
+                               } else {
                                        out.attr(ns, key, value);
+                               }
                        }
                }
 
@@ -569,14 +601,15 @@ public class XmlSerializer extends WriterSerializer {
                        BeanPropertyMeta pMeta = p.getMeta();
                        ClassMeta<?> cMeta = p.getClassMeta();
 
-                       XmlFormat xf = 
pMeta.getExtendedMeta(XmlBeanPropertyMeta.class).getXmlFormat();
-
-                       if (xf == CONTENT) {
+                       String n = p.getName();
+                       if (n.equals(contentProperty)) {
                                content = p.getValue();
+                               contentType = p.getClassMeta();
                                hasContent = true;
-                       } else if (xf == ATTR) {
-                               // Do nothing
-                       } else {
+                               cf = xbm.getContentFormat();
+                               if (cf.isOneOf(MIXED,TEXT,XMLTEXT))
+                                       isMixed = true;
+                       } else if (elements.contains(n) || 
collapsedElements.contains(n)) {
                                String key = p.getName();
                                Object value = p.getValue();
                                Throwable t = p.getThrown();
@@ -588,52 +621,74 @@ public class XmlSerializer extends WriterSerializer {
 
                                if (! hasChildren) {
                                        hasChildren = true;
-                                       out.appendIf(! isCollapsed, '>').nl();
+                                       out.appendIf(! isCollapsed, '>').nlIf(! 
isMixed);
                                }
-                               serializeAnything(session, out, value, cMeta, 
key, pMeta.getExtendedMeta(XmlBeanPropertyMeta.class).getNamespace(), false, 
pMeta.getExtendedMeta(XmlBeanPropertyMeta.class).getXmlFormat(), pMeta);
+
+                               XmlBeanPropertyMeta xbpm = 
pMeta.getExtendedMeta(XmlBeanPropertyMeta.class);
+                               serializeAnything(session, out, value, cMeta, 
key, xbpm.getNamespace(), false, xbpm.getXmlFormat(), isMixed, pMeta);
                        }
                }
                if ((! hasContent) || session.canIgnoreValue(string(), null, 
content))
-                       return hasChildren;
-               out.append('>').cr(session.indent);
+                       return (hasChildren ? CR_ELEMENTS : CR_EMPTY);
+               out.append('>').nlIf(! isMixed);
 
                // Serialize XML content.
-               XmlContentHandler h = 
bm.getExtendedMeta(XmlBeanMeta.class).getXmlContentHandler();
-               if (h != null)
-                       h.serialize(out, m.getBean());
-               else
-                       out.encodeText(content);
-               out.nl();
-               return true;
+               if (content != null) {
+                       if (contentType == null) {
+                       } else if (contentType.isCollection()) {
+                               Collection c = (Collection)content;
+                               for (Iterator i = c.iterator(); i.hasNext();) {
+                                       Object value = i.next();
+                                       serializeAnything(session, out, value, 
contentType.getElementType(), null, null, false, cf, isMixed, null);
+                               }
+                       } else if (contentType.isArray()) {
+                               Collection c = toList(Object[].class, content);
+                               for (Iterator i = c.iterator(); i.hasNext();) {
+                                       Object value = i.next();
+                                       serializeAnything(session, out, value, 
contentType.getElementType(), null, null, false, cf, isMixed, null);
+                               }
+                       } else {
+                               serializeAnything(session, out, content, 
contentType, null, null, false, cf, isMixed, null);
+                       }
+               } else {
+                       if (! session.isTrimNulls()) {
+                               if (! isMixed)
+                                       out.i(session.indent);
+                               out.encodeText(content);
+                               if (! isMixed)
+                                       out.nl();
+                       }
+               }
+               return isMixed ? CR_MIXED : CR_ELEMENTS;
        }
 
-       private XmlWriter serializeCollection(XmlSerializerSession session, 
XmlWriter out, Collection c, ClassMeta<?> type, BeanPropertyMeta ppMeta) throws 
Exception {
+       private XmlWriter serializeCollection(XmlSerializerSession session, 
XmlWriter out, Object in, ClassMeta<?> sType, ClassMeta<?> eType, 
BeanPropertyMeta ppMeta, boolean isMixed) throws Exception {
+
+               ClassMeta<?> seType = sType.getElementType();
+               if (seType == null)
+                       seType = session.object();
+               ClassMeta<?> eeType = eType.getElementType();
+
+               Collection c = (sType.isCollection() ? (Collection)in : 
toList(sType.getInnerClass(), in));
 
                c = session.sort(c);
 
-               ClassMeta<?> elementType = type.getElementType();
+               String type2 = null;
+               if (sType != eType)
+                       type2 = sType.getDictionaryName();
 
-               String eName = null;
+               String eName = type2;
                Namespace eNs = null;
 
                if (ppMeta != null) {
-                       eName = 
ppMeta.getExtendedMeta(XmlBeanPropertyMeta.class).getChildName();
-                       eNs = 
ppMeta.getExtendedMeta(XmlBeanPropertyMeta.class).getNamespace();
-               }
-
-               if (eName == null) {
-                       eName = 
type.getExtendedMeta(XmlClassMeta.class).getChildName();
-                       eNs = 
type.getExtendedMeta(XmlClassMeta.class).getNamespace();
-               }
-
-               if (eName == null && ! elementType.isObject()) {
-                       eName = elementType.getDictionaryName();
-                       eNs = 
elementType.getExtendedMeta(XmlClassMeta.class).getNamespace();
+                       XmlBeanPropertyMeta xbpm = 
ppMeta.getExtendedMeta(XmlBeanPropertyMeta.class);
+                       eName = xbpm.getChildName();
+                       eNs = xbpm.getNamespace();
                }
 
                for (Iterator i = c.iterator(); i.hasNext();) {
                        Object value = i.next();
-                       serializeAnything(session, out, value, elementType, 
eName, eNs, false, NORMAL, null);
+                       serializeAnything(session, out, value, eeType, eName, 
eNs, false, XmlFormat.DEFAULT, isMixed, null);
                }
                return out;
        }
@@ -647,6 +702,36 @@ public class XmlSerializer extends WriterSerializer {
                return s;
        }
 
+       static enum JsonType {
+               
STRING("string"),BOOLEAN("boolean"),NUMBER("number"),ARRAY("array"),OBJECT("object"),NULL("null");
+
+               private final String value;
+               private JsonType(String value) {
+                       this.value = value;
+               }
+
+               @Override
+               public String toString() {
+                       return value;
+               }
+
+               boolean isOneOf(JsonType...types) {
+                       for (JsonType type : types)
+                               if (type == this)
+                                       return true;
+                       return false;
+               }
+       }
+
+       /**
+        * 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.
+       }
+
 
        
//--------------------------------------------------------------------------------
        // Overridden methods
@@ -657,7 +742,7 @@ public class XmlSerializer extends WriterSerializer {
                XmlSerializerSession s = (XmlSerializerSession)session;
                if (s.isEnableNamespaces() && s.isAutoDetectNamespaces())
                        findNsfMappings(s, o);
-               serializeAnything(s, s.getWriter(), o, null, null, null, 
s.isEnableNamespaces() && s.isAddNamespaceUrlsToRoot(), NORMAL, null);
+               serializeAnything(s, s.getWriter(), o, null, null, null, 
s.isEnableNamespaces() && s.isAddNamespaceUrlsToRoot(), XmlFormat.DEFAULT, 
false, null);
        }
 
        @Override /* Serializer */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/4fb01038/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializerContext.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializerContext.java 
b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializerContext.java
index 9b7b65c..d1d51df 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializerContext.java
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializerContext.java
@@ -38,24 +38,10 @@ import org.apache.juneau.serializer.*;
  * <table class='styled' style='border-collapse: collapse;'>
  *     <tr><th>Setting name</th><th>Description</th><th>Data 
type</th><th>Default value</th><th>Session overridable</th></tr>
  *     <tr>
- *             <td>{@link #XML_addJsonTypeAttrs}</td>
- *             <td>Add JSON type attributes to output.</td>
- *             <td><code>Boolean</code></td>
- *             <td><jk>false</jk></td>
- *             <td><jk>true</jk></td>
- *     </tr>
- *     <tr>
- *             <td>{@link #XML_addJsonStringTypeAttrs}</td>
- *             <td>Add JSON type attributes for strings to output.</td>
- *             <td><code>Boolean</code></td>
- *             <td><jk>false</jk></td>
- *             <td><jk>true</jk></td>
- *     </tr>
- *     <tr>
  *             <td>{@link #XML_enableNamespaces}</td>
  *             <td>Enable support for XML namespaces.</td>
  *             <td><code>Boolean</code></td>
- *             <td><jk>true</jk></td>
+ *             <td><jk>false</jk></td>
  *             <td><jk>true</jk></td>
  *     </tr>
  *     <tr>
@@ -69,11 +55,11 @@ import org.apache.juneau.serializer.*;
  *             <td>{@link #XML_addNamespaceUrisToRoot}</td>
  *             <td>Add namespace URLs to the root element.</td>
  *             <td><code>Boolean</code></td>
- *             <td><jk>true</jk></td>
+ *             <td><jk>false</jk></td>
  *             <td><jk>true</jk></td>
  *     </tr>
  *     <tr>
- *             <td>{@link #XML_defaultNamespaceUri}</td>
+ *             <td>{@link #XML_defaultNamespace}</td>
  *             <td>Default namespace URI.</td>
  *             <td><code>String</code></td>
  *             <td><jk>null</jk></td>
@@ -87,13 +73,6 @@ import org.apache.juneau.serializer.*;
  *             <td><jk>true</jk></td>
  *     </tr>
  *     <tr>
- *             <td>{@link #XML_xsiNamespace}</td>
- *             <td>XMLSchema-Instance namespace.</td>
- *             <td>{@link Namespace}</td>
- *             
<td><code>{name:<js>'xsi'</js>,uri:<js>'http://www.w3.org/2001/XMLSchema-instance'</js>}</code></td>
- *             <td><jk>true</jk></td>
- *     </tr>
- *     <tr>
  *             <td>{@link #XML_namespaces}</td>
  *             <td>Default namespaces.</td>
  *             <td><code>Set&lt;{@link Namespace}&gt;</code></td>
@@ -113,45 +92,12 @@ import org.apache.juneau.serializer.*;
 public class XmlSerializerContext extends SerializerContext {
 
        /**
-        * <b>Configuration property:</b>  Add JSON type attributes to output.
-        * <p>
-        * <ul>
-        *      <li><b>Name:</b> <js>"XmlSerializer.addJsonTypeAttrs"</js>
-        *      <li><b>Data type:</b> <code>Boolean</code>
-        *      <li><b>Default:</b> <jk>false</jk>
-        *      <li><b>Session-overridable:</b> <jk>true</jk>
-        * </ul>
-        * <p>
-        * If <js>true</jk>, {@code type} attributes will be added to elements 
in the XML for number/boolean/null nodes.
-        */
-       public static final String XML_addJsonTypeAttrs = 
"XmlSerializer.addJsonTypeAttrs";
-
-       /**
-        * <b>Configuration property:</b>  Add JSON type attributes for strings 
to output.
-        * <p>
-        * <ul>
-        *      <li><b>Name:</b> <js>"XmlSerializer.addJsonStringTypeAttrs"</js>
-        *      <li><b>Data type:</b> <code>Boolean</code>
-        *      <li><b>Default:</b> <jk>false</jk>
-        *      <li><b>Session-overridable:</b> <jk>true</jk>
-        * </ul>
-        * <p>
-        * If <jk>true</jk>, {@code type} attributes will be added to elements 
in the XML for string nodes.
-        * <p>
-        * By default, these attributes are not added, and the parser will 
assume that the content type
-        * of the node is string by default.
-        * <p>
-        * This feature is disabled if {@link #XML_addJsonTypeAttrs} is 
disabled.
-        */
-       public static final String XML_addJsonStringTypeAttrs = 
"XmlSerializer.addJsonStringTypeAttrs";
-
-       /**
         * <b>Configuration property:</b>  Enable support for XML namespaces.
         * <p>
         * <ul>
         *      <li><b>Name:</b> <js>"XmlSerializer.enableNamespaces"</js>
         *      <li><b>Data type:</b> <code>Boolean</code>
-        *      <li><b>Default:</b> <jk>true</jk>
+        *      <li><b>Default:</b> <jk>false</jk>
         *      <li><b>Session-overridable:</b> <jk>true</jk>
         * </ul>
         * <p>
@@ -194,7 +140,7 @@ public class XmlSerializerContext extends SerializerContext 
{
         * <ul>
         *      <li><b>Name:</b> <js>"XmlSerializer.addNamespaceUrisToRoot"</js>
         *      <li><b>Data type:</b> <code>Boolean</code>
-        *      <li><b>Default:</b> <jk>true</jk>
+        *      <li><b>Default:</b> <jk>false</jk>
         *      <li><b>Session-overridable:</b> <jk>true</jk>
         * </ul>
         * <p>
@@ -206,18 +152,18 @@ public class XmlSerializerContext extends 
SerializerContext {
        public static final String XML_addNamespaceUrisToRoot = 
"XmlSerializer.addNamespaceUrisToRoot";
 
        /**
-        * <b>Configuration property:</b>  Default namespace URI.
+        * <b>Configuration property:</b>  Default namespace.
         * <p>
         * <ul>
-        *      <li><b>Name:</b> <js>"XmlSerializer.defaultNamespaceUri"</js>
+        *      <li><b>Name:</b> <js>"XmlSerializer.defaultNamespace"</js>
         *      <li><b>Data type:</b> <code>String</code>
-        *      <li><b>Default:</b> <jk>null</jk>
+        *      <li><b>Default:</b> 
<js>"{juneau:'http://www.apache.org/2013/Juneau'}"</js>
         *      <li><b>Session-overridable:</b> <jk>true</jk>
         * </ul>
         * <p>
         * Specifies the default namespace URI for this document.
         */
-       public static final String XML_defaultNamespaceUri = 
"XmlSerializer.defaultNamespaceUri";
+       public static final String XML_defaultNamespace = 
"XmlSerializer.defaultNamespace";
 
        /**
         * <b>Configuration property:</b>  XMLSchema namespace.
@@ -235,20 +181,6 @@ public class XmlSerializerContext extends 
SerializerContext {
        public static final String XML_xsNamespace = 
"XmlSerializer.xsNamespace";
 
        /**
-        * <b>Configuration property:</b>  XMLSchema-Instance namespace.
-        * <p>
-        * <ul>
-        *      <li><b>Name:</b> <js>"XmlSerializer.xsiNamespace"</js>
-        *      <li><b>Data type:</b> {@link Namespace}
-        *      <li><b>Default:</b> 
<code>{name:<js>'xsi'</js>,uri:<js>'http://www.w3.org/2001/XMLSchema-instance'</js>}</code>
-        *      <li><b>Session-overridable:</b> <jk>true</jk>
-        * </ul>
-        * <p>
-        * Specifies the namespace of the <code>XMLSchema-instance</code> 
namespace used for<code>nil=<jk>true</jk></code> attributes.
-        */
-       public static final String XML_xsiNamespace = 
"XmlSerializer.xsiNamespace";
-
-       /**
         * <b>Configuration property:</b>  Default namespaces.
         * <p>
         * <ul>
@@ -260,12 +192,10 @@ public class XmlSerializerContext extends 
SerializerContext {
         * <p>
         * The default list of namespaces associated with this serializer.
         */
-       public static final String XML_namespaces = "XmlSerializer.namespaces";
+       public static final String XML_namespaces = 
"XmlSerializer.namespaces.list";
 
 
        final boolean
-               addJsonTypeAttrs,
-               addJsonStringTypeAttrs,
                autoDetectNamespaces,
                enableNamespaces,
                addNamespaceUrlsToRoot;
@@ -273,7 +203,6 @@ public class XmlSerializerContext extends SerializerContext 
{
        final String defaultNamespace;
 
        final Namespace
-               xsiNamespace,
                xsNamespace;
 
        final Namespace[] namespaces;
@@ -287,14 +216,11 @@ public class XmlSerializerContext extends 
SerializerContext {
         */
        public XmlSerializerContext(ContextFactory cf) {
                super(cf);
-               addJsonTypeAttrs = cf.getProperty(XML_addJsonTypeAttrs, 
boolean.class, false);
-               addJsonStringTypeAttrs = 
cf.getProperty(XML_addJsonStringTypeAttrs, boolean.class, false);
                autoDetectNamespaces = cf.getProperty(XML_autoDetectNamespaces, 
boolean.class, true);
-               enableNamespaces = cf.getProperty(XML_enableNamespaces, 
boolean.class, true);
-               addNamespaceUrlsToRoot = 
cf.getProperty(XML_addNamespaceUrisToRoot, boolean.class, true);
-               defaultNamespace = cf.getProperty(XML_defaultNamespaceUri, 
String.class, "{juneau:'http://www.apache.org/2013/Juneau'}");
+               enableNamespaces = cf.getProperty(XML_enableNamespaces, 
boolean.class, false);
+               addNamespaceUrlsToRoot = 
cf.getProperty(XML_addNamespaceUrisToRoot, boolean.class, false);
+               defaultNamespace = cf.getProperty(XML_defaultNamespace, 
String.class, "{juneau:'http://www.apache.org/2013/Juneau'}");
                xsNamespace = cf.getProperty(XML_xsNamespace, Namespace.class, 
new Namespace("xs", "http://www.w3.org/2001/XMLSchema";));
-               xsiNamespace = cf.getProperty(XML_xsiNamespace, 
Namespace.class, new Namespace("xsi", 
"http://www.w3.org/2001/XMLSchema-instance";));
                namespaces = cf.getProperty(XML_namespaces, Namespace[].class, 
new Namespace[0]);
        }
 
@@ -302,14 +228,11 @@ public class XmlSerializerContext extends 
SerializerContext {
        public ObjectMap asMap() {
                return super.asMap()
                        .append("XmlSerializerContext", new ObjectMap()
-                               .append("addJsonTypeAttrs", addJsonTypeAttrs)
-                               .append("addJsonStringTypeAttrs", 
addJsonStringTypeAttrs)
                                .append("autoDetectNamespaces", 
autoDetectNamespaces)
                                .append("enableNamespaces", enableNamespaces)
                                .append("addNamespaceUrlsToRoot", 
addNamespaceUrlsToRoot)
                                .append("defaultNamespace", defaultNamespace)
                                .append("xsNamespace", xsNamespace)
-                               .append("xsiNamespace", xsiNamespace)
                                .append("namespaces", namespaces)
                        );
        }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/4fb01038/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 dfdd942..6a13cb4 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
@@ -32,8 +32,6 @@ import org.apache.juneau.serializer.*;
 public class XmlSerializerSession extends SerializerSession {
 
        private final boolean
-               addJsonTypeAttrs,
-               addJsonStringTypeAttrs,
                autoDetectNamespaces,
                enableNamespaces,
                addNamespaceUrlsToRoot;
@@ -41,7 +39,6 @@ public class XmlSerializerSession extends SerializerSession {
        private Namespace
                defaultNamespace;
        private final Namespace
-               xsiNamespace,
                xsNamespace;
 
        private Namespace[] namespaces = new Namespace[0];
@@ -63,24 +60,18 @@ public class XmlSerializerSession extends SerializerSession 
{
        public XmlSerializerSession(XmlSerializerContext ctx, ObjectMap op, 
Object output, Method javaMethod, Locale locale, TimeZone timeZone) {
                super(ctx, op, output, javaMethod, locale, timeZone);
                if (op == null || op.isEmpty()) {
-                       addJsonTypeAttrs = ctx.addJsonTypeAttrs;
-                       addJsonStringTypeAttrs = ctx.addJsonStringTypeAttrs;
                        enableNamespaces = ctx.enableNamespaces;
                        autoDetectNamespaces = ctx.autoDetectNamespaces;
                        addNamespaceUrlsToRoot = ctx.addNamespaceUrlsToRoot;
                        addNamespaces(ctx.namespaces);
                        defaultNamespace = 
findDefaultNamespace(ctx.defaultNamespace);
-                       xsiNamespace = ctx.xsiNamespace;
                        xsNamespace = ctx.xsNamespace;
                } else {
-                       addJsonTypeAttrs = op.getBoolean(XML_addJsonTypeAttrs, 
ctx.addJsonTypeAttrs);
-                       addJsonStringTypeAttrs = 
op.getBoolean(XML_addJsonStringTypeAttrs, ctx.addJsonStringTypeAttrs);
                        enableNamespaces = op.getBoolean(XML_enableNamespaces, 
ctx.enableNamespaces);
                        autoDetectNamespaces = 
op.getBoolean(XML_autoDetectNamespaces, ctx.autoDetectNamespaces);
                        addNamespaceUrlsToRoot = 
op.getBoolean(XML_addNamespaceUrisToRoot, ctx.addNamespaceUrlsToRoot);
                        namespaces = (op.containsKey(XML_namespaces) ? 
parseNamespaces(op.get(XML_namespaces)) : ctx.namespaces);
-                       defaultNamespace = 
findDefaultNamespace(op.containsKey(XML_defaultNamespaceUri) ? 
op.getString(XML_defaultNamespaceUri) : ctx.defaultNamespace);
-                       xsiNamespace = (op.containsKey(XML_xsiNamespace) ? 
parseNamespace(op.get(XML_xsiNamespace)) : ctx.xsiNamespace);
+                       defaultNamespace = 
findDefaultNamespace(op.containsKey(XML_defaultNamespace) ? 
op.getString(XML_defaultNamespace) : ctx.defaultNamespace);
                        xsNamespace = (op.containsKey(XML_xsNamespace) ? 
parseNamespace(op.get(XML_xsNamespace)) : ctx.xsNamespace);
                }
        }
@@ -129,24 +120,6 @@ public class XmlSerializerSession extends 
SerializerSession {
        }
 
        /**
-        * Returns the {@link XmlSerializerContext#XML_addJsonTypeAttrs} 
setting value in this context.
-        *
-        * @return The {@link XmlSerializerContext#XML_addJsonTypeAttrs} 
setting value in this context.
-        */
-       public final boolean isAddJsonTypeAttrs() {
-               return addJsonTypeAttrs;
-       }
-
-       /**
-        * Returns the {@link XmlSerializerContext#XML_addJsonStringTypeAttrs} 
setting value in this context.
-        *
-        * @return The {@link XmlSerializerContext#XML_addJsonStringTypeAttrs} 
setting value in this context.
-        */
-       public final boolean isAddJsonStringTypeAttrs() {
-               return addJsonStringTypeAttrs;
-       }
-
-       /**
         * Returns the {@link XmlSerializerContext#XML_autoDetectNamespaces} 
setting value in this context.
         *
         * @return The {@link XmlSerializerContext#XML_autoDetectNamespaces} 
setting value in this context.
@@ -174,24 +147,15 @@ public class XmlSerializerSession extends 
SerializerSession {
        }
 
        /**
-        * Returns the {@link XmlSerializerContext#XML_defaultNamespaceUri} 
setting value in this context.
+        * Returns the {@link XmlSerializerContext#XML_defaultNamespace} 
setting value in this context.
         *
-        * @return The {@link XmlSerializerContext#XML_defaultNamespaceUri} 
setting value in this context.
+        * @return The {@link XmlSerializerContext#XML_defaultNamespace} 
setting value in this context.
         */
        public final Namespace getDefaultNamespace() {
                return defaultNamespace;
        }
 
        /**
-        * Returns the {@link XmlSerializerContext#XML_xsiNamespace} setting 
value in this context.
-        *
-        * @return The {@link XmlSerializerContext#XML_xsiNamespace} setting 
value in this context.
-        */
-       public final Namespace getXsiNamespace() {
-               return xsiNamespace;
-       }
-
-       /**
         * Returns the {@link XmlSerializerContext#XML_xsNamespace} setting 
value in this context.
         *
         * @return The {@link XmlSerializerContext#XML_xsNamespace} setting 
value in this context.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/4fb01038/juneau-core/src/main/java/org/apache/juneau/xml/XmlUtils.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/XmlUtils.java 
b/juneau-core/src/main/java/org/apache/juneau/xml/XmlUtils.java
index b512537..4ca4b20 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/XmlUtils.java
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlUtils.java
@@ -234,16 +234,18 @@ public final class XmlUtils {
         * Translates any _x####_ sequences (introduced by the various encode 
methods) back into their original characters.
         *
         * @param s The string being decoded.
+        * @param sb The string builder to use as a scratch pad.
         * @return The decoded string.
         */
-       public static final String decode(String s) {
+       public static final String decode(String s, StringBuilder sb) {
                if (s == null) return null;
                if (s.length() == 0)
                        return s;
                if (s.indexOf('_') == -1)
                        return s;
 
-               StringBuffer sb = new StringBuffer(s.length());
+               if (sb == null)
+                       sb = new StringBuilder(s.length());
                for (int i = 0; i < s.length(); i++) {
                        char c = s.charAt(i);
                        if (c == '_' && isEscapeSequence(s,i)) {
@@ -570,4 +572,45 @@ public final class XmlUtils {
 
                return null;
        }
+
+       /**
+        * Utility method that converts the current event on the XML stream to 
something human-readable for debug purposes.
+        *
+        * @param r The XML stream reader whose current event is to be 
converted to a readable string.
+        * @return The event in human-readable form.
+        */
+       public static final String toReadableEvent(XMLStreamReader r) {
+               int t = r.getEventType();
+               if (t == 1)
+                       return "<"+r.getLocalName()+">";
+               if (t == 2)
+                       return "</"+r.getLocalName()+">";
+               if (t == 3)
+                       return "PROCESSING_INSTRUCTION";
+               if (t == 4)
+                       return "CHARACTERS=[" + r.getText() + "]";
+               if (t == 5)
+                       return "COMMENTS=[" + r.getText() + "]";
+               if (t == 6)
+                       return "SPACE=[" + r.getText() + "]";
+               if (t == 7)
+                       return "START_DOCUMENT";
+               if (t == 8)
+                       return "END_DOCUMENT";
+               if (t == 9)
+                       return "ENTITY_REFERENCE";
+               if (t == 10)
+                       return "ATTRIBUTE";
+               if (t == 11)
+                       return "DTD";
+               if (t == 12)
+                       return "CDATA=["+r.getText()+"]";
+               if (t == 13)
+                       return "NAMESPACE";
+               if (t == 14)
+                       return "NOTATION_DECLARATION";
+               if (t == 15)
+                       return "ENTITY_DECLARATION";
+               return "UNKNOWN";
+       }
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/4fb01038/juneau-core/src/main/java/org/apache/juneau/xml/annotation/Xml.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/xml/annotation/Xml.java 
b/juneau-core/src/main/java/org/apache/juneau/xml/annotation/Xml.java
index c9e7f50..e901f58 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/annotation/Xml.java
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/annotation/Xml.java
@@ -17,8 +17,6 @@ import static java.lang.annotation.RetentionPolicy.*;
 
 import java.lang.annotation.*;
 
-import org.apache.juneau.xml.*;
-
 /**
  * Annotation for specifying various XML options for the XML and RDF/XML 
serializers.
  * <p>
@@ -144,12 +142,5 @@ public @interface Xml {
         *      <xt>&lt;/object&gt;</xt>
         * </p>
         */
-       XmlFormat format() default XmlFormat.NORMAL;
-
-       /**
-        * Associates a content handler with a bean class or bean property.
-        * <p>
-        *      Refer to {@link XmlContentHandler} for more information.
-        */
-       Class<? extends XmlContentHandler<?>> contentHandler() default 
XmlContentHandler.NULL.class;
+       XmlFormat format() default XmlFormat.DEFAULT;
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/4fb01038/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 e6fb499..98140b6 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
@@ -18,21 +18,30 @@ package org.apache.juneau.xml.annotation;
 public enum XmlFormat {
 
        /**
-        * Normal formatting (default)
+        * Normal formatting (default).
+        * <p>
+        * On a bean class, implies {@link #ELEMENTS} meaning bean properties 
will be serialized as child elements by default.
+        * <p>
+        * On a bean property, implies {@link #ELEMENT} meaning the bean 
property will be serialized as a child element.
         */
-       NORMAL,
+       DEFAULT,
 
        /**
-        * Render property as an attribute instead of an element.
+        * Render a bean property as an attribute instead of an element.
         * <p>
-        *      Can only be applied to properties (methods/fields) of class 
types that can be convertible to <code>Strings</code>.
+        * Only applicable for bean properties, not bean classes.
+        * <p>
+        * Can only be applied to properties (methods/fields) of class types 
that can be convertible to <code>Strings</code>.
         */
        ATTR,
 
        /**
         * Render property as attributes instead of an element.
         * <p>
-        *      Can only be applied to properties (methods/fields) of class 
type <code>Map&lt;Object,Object&gt;</code> where both
+        * On a bean class, implies bean properties will be serialized as 
attributes instead of child elements by default.
+        * <p>
+        * On bean properties, implies that the bean property value itself 
should be serialized as attributes on the bean element.
+        * The bean property data type must be of class type 
<code>Map&lt;Object,Object&gt;</code> where both
         *      objects are convertible to <code>Strings</code>.
         */
        ATTRS,
@@ -40,29 +49,75 @@ public enum XmlFormat {
        /**
         * Render property as an element instead of an attribute.
         * <p>
-        *      Can be applied to URL and ID bean properties that would 
normally be rendered as attributes.
+        * Only applicable for bean properties, not bean classes.
+        * <p>
+        * Used to override the behavior of the {@link #ATTRS} format applied 
to the bean class.
         */
        ELEMENT,
 
        /**
-        * Prevents collections and arrays from being enclosed in 
<xt>&lt;array&gt;</xt> elements.
+        * Render property value directly as the contents of the element.
+        * <p>
+        * On a bean class, implies that bean properties will be serialized as 
child elements.
+        * Note that this is equivalent to {@link #DEFAULT}.
+        * <p>
+        * Only applicable for objects of type array/Collection.
+        * <p>
+        * On a bean property, implies that the bean property value itself 
should be serialized as child elements of the bean element.
+        */
+       ELEMENTS,
+
+       /**
+        * Same as {@link #ELEMENTS} except primitive types (e.g. 
string/boolean/number/null) are not wrapped in elements.
+        * <p>
+        * Only applicable for bean properties, not bean classes.
         * <p>
-        *      Can only be applied to properties (methods/fields) of type 
collection or array, or collection classes.
+        * Only applicable for objects of type array/Collection.
+        * <p>
+        * Use of this format may cause data type loss during parsing if the 
types cannot be inferred through reflection.
+        */
+       MIXED,
+
+       /**
+        * Render property value as the text content of the element.
+        * <p>
+        * Similar to {@link #MIXED} but value must be a single value, not a 
collection.
+        * <p>
+        * Only applicable for bean properties, not bean classes.
+        * <p>
+        * Use of this format may cause data type loss during parsing if the 
type cannot be inferred through reflection.
         */
-       COLLAPSED,
+       TEXT,
 
        /**
-        * Render property value directly as content of element.
+        * Same as {@link #TEXT} except the content is expected to be 
fully-formed XML that will
+        * get serialized as-is.
         * <p>
-        *      By default, content is converted to plain text.
+        * During parsing, this XML text will be reserialized and set on the 
property.
+        * <p>
+        * Only applicable for bean properties, not bean classes.
+        * <p>
+        * Use of this format may cause data type loss during parsing if the 
type cannot be inferred through reflection.
+        */
+       XMLTEXT,
+
+       /**
+        * Prevents collections and arrays from being enclosed in 
<xt>&lt;array&gt;</xt> elements.
         * <p>
-        *      Can be used in combination with {@link Xml#contentHandler()} to 
produce something other
-        *      than plain text, such as embedded XML.
+        * Can only be applied to properties (methods/fields) of type 
collection or array, or collection classes.
         */
-       CONTENT,
+       COLLAPSED;
 
        /**
-        * Render a collection/array as mixed child content of the element.
+        * Returns <jk>true</jk> if this format is one of those specified.
+        *
+        * @param formats The formats to match against.
+        * @return <jk>true</jk> if this format is one of those specified.
         */
-       MIXED
+       public boolean isOneOf(XmlFormat...formats) {
+               for (XmlFormat format : formats)
+                       if (format == this)
+                               return true;
+               return false;
+       }
 }
\ No newline at end of file


Reply via email to