title: How do I embed an Object as a @XmlValue in JAXB?
body: <p>I would like to represent an instance of <code>List&lt;Map&lt;String,Object&gt;&gt;</code> in XML as follows:</p>
  
  <pre><code>&lt;row&gt;
     &lt;entry key="key1" xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;value1&lt;/entry&gt;
     &lt;entry key="key2" xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;value2&lt;/entry&gt;
     &lt;entry key="key3" /&gt;
     &lt;entry key="keyDate" xsi:type="xs:dateTime" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;2012-08-19T13:00:59.412-04:00&lt;/entry&gt;
  &lt;/row&gt;
  </code></pre>
  
  <p>where <code>key1</code> and <code>key2</code> are Strings, <code>key3</code> is nil, and <code>keyDate</code> is a date.</p>
  
  <p>I can get <em>close</em> to this using the following implementation of <code>XmlAdapter</code>:</p>
  
  <pre><code>package net.parkerson.test1;
  
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  import java.util.Map.Entry;
  import javax.xml.bind.annotation.XmlAttribute;
  import javax.xml.bind.annotation.XmlElement;
  import javax.xml.bind.annotation.adapters.XmlAdapter;
  
  public class JAXBMapAdapter extends XmlAdapter&lt;JAXBMapAdapter.JAXBMap, Map&lt;String, Object&gt;&gt;
  {
  
      @Override
      public JAXBMap marshal(Map&lt;String, Object&gt; map) throws Exception
      {
          JAXBMap jaxbMap = new JAXBMap();
          for (Entry&lt;String, Object&gt; entry : map.entrySet())
          {
              jaxbMap.entry.add(new JAXBMapEntry(entry));
          }
          return jaxbMap;
  
      }
  
      @Override
      public Map&lt;String, Object&gt; unmarshal(JAXBMapAdapter.JAXBMap mappedObject) throws Exception
      {
          HashMap&lt;String, Object&gt; map = new HashMap&lt;String, Object&gt;();
          for (JAXBMapEntry entry : mappedObject.entry)
          {
              map.put(entry.key, entry.value);
          }
          return map;
      }
  
      public static class JAXBMapEntry
      {
  
          @XmlAttribute
          public String key;
  
          @XmlElement
          public Object value;
  
          public JAXBMapEntry()
          {
          }
  
          public JAXBMapEntry(Map.Entry&lt;String, Object&gt; entry)
          {
              key = entry.getKey();
              value = entry.getValue();
          }
      }
  
      public static class JAXBMap
      {
          public List&lt;JAXBMapAdapter.JAXBMapEntry&gt; entry = new ArrayList&lt;JAXBMapAdapter.JAXBMapEntry&gt;();
      }
  }
  </code></pre>
  
  <p>and the following test code:</p>
  
  <pre><code>package net.parkerson.test1;
  
  import java.util.ArrayList;
  import java.util.Date;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  
  import javax.xml.bind.JAXB;
  import javax.xml.bind.annotation.XmlElement;
  import javax.xml.bind.annotation.XmlElements;
  import javax.xml.bind.annotation.XmlRootElement;
  import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
  
  import net.parkerson.test1.JAXBMapAdapter;
  
  public class Test1
  {
      @XmlRootElement
      public static class Thingy
      {
          @XmlElements(@XmlElement(name = "row"))
          @XmlJavaTypeAdapter(type=Map.class, value=JAXBMapAdapter.class)
          public List&lt;Map&lt;String,Object&gt;&gt; rows;
      }
  
      public static void main(String[] args) throws Exception
      {
          Test1.Thingy thingy = new Test1.Thingy();
  
          Map&lt;String,Object&gt; thing1 = new HashMap&lt;String,Object&gt;();
          thing1.put("foo", "bar");
          thing1.put("date", new Date());
  
          Map&lt;String,Object&gt; thing2 = new HashMap&lt;String,Object&gt;();
          thing2.put("foo", "baz");
          thing2.put("date", new Date());
  
          List&lt;Map&lt;String,Object&gt;&gt; things = new ArrayList&lt;Map&lt;String,Object&gt;&gt;();
          things.add(thing1);
          things.add(thing2);
  
          thingy.rows = things;
  
          java.io.StringWriter sw = new java.io.StringWriter();
          JAXB.marshal(thingy, sw);
          System.out.print(sw.toString());
      }
  
  }
  </code></pre>
  
  <p>which generates this:</p>
  
  <pre><code>&lt;thingy&gt;
      &lt;row&gt;
          &lt;entry key="foo"&gt;
              &lt;value xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;bar&lt;/value&gt;
          &lt;/entry&gt;
          &lt;entry key="date"&gt;
              &lt;value xsi:type="xs:dateTime" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;2012-08-19T13:20:57.484-04:00&lt;/value&gt;
          &lt;/entry&gt;
      &lt;/row&gt;
      &lt;row&gt;
          &lt;entry key="foo"&gt;
              &lt;value xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;baz&lt;/value&gt;
          &lt;/entry&gt;
          &lt;entry key="date"&gt;
              &lt;value xsi:type="xs:dateTime" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;2012-08-19T13:20:57.484-04:00&lt;/value&gt;
          &lt;/entry&gt;
      &lt;/row&gt;
  &lt;/thingy&gt;
  </code></pre>
  
  <p>What I really want is to ditch the nested <code>value</code> tag inside of the entry. My naive assumption was that I could replace the <code>@XmlElement</code> annotation on <code>value</code> to <code>@XmlValue</code>. However, this cause JAXB to puke all over the floor thusly:</p>
  
  <pre><code>Exception in thread "main" java.lang.NullPointerException
      at com.sun.xml.internal.bind.v2.runtime.reflect.TransducedAccessor.get(TransducedAccessor.java:154)
      at com.sun.xml.internal.bind.v2.runtime.property.ValueProperty.&lt;init&gt;(ValueProperty.java:66)
      at com.sun.xml.internal.bind.v2.runtime.property.PropertyFactory.create(PropertyFactory.java:95)
      at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.&lt;init&gt;(ClassBeanInfoImpl.java:145)
      at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:479)
      at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:498)
      at com.sun.xml.internal.bind.v2.runtime.property.ArrayElementProperty.&lt;init&gt;(ArrayElementProperty.java:97)
      at com.sun.xml.internal.bind.v2.runtime.property.ArrayElementNodeProperty.&lt;init&gt;(ArrayElementNodeProperty.java:47)
      at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
      at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
      at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
      at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
      at com.sun.xml.internal.bind.v2.runtime.property.PropertyFactory.create(PropertyFactory.java:113)
      at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.&lt;init&gt;(ClassBeanInfoImpl.java:145)
      at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:479)
      at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:498)
      at com.sun.xml.internal.bind.v2.runtime.property.ArrayElementProperty.&lt;init&gt;(ArrayElementProperty.java:97)
      at com.sun.xml.internal.bind.v2.runtime.property.ArrayElementNodeProperty.&lt;init&gt;(ArrayElementNodeProperty.java:47)
      at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
      at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
      at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
      at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
      at com.sun.xml.internal.bind.v2.runtime.property.PropertyFactory.create(PropertyFactory.java:113)
      at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.&lt;init&gt;(ClassBeanInfoImpl.java:145)
      at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:479)
      at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.&lt;init&gt;(JAXBContextImpl.java:305)
      at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1100)
      at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:143)
      at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:110)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:597)
      at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:202)
      at javax.xml.bind.ContextFinder.find(ContextFinder.java:376)
      at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:574)
      at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:522)
      at javax.xml.bind.JAXB$Cache.&lt;init&gt;(JAXB.java:87)
      at javax.xml.bind.JAXB.getContext(JAXB.java:114)
      at javax.xml.bind.JAXB._marshal(JAXB.java:538)
      at javax.xml.bind.JAXB.marshal(JAXB.java:431)
      at net.parkerson.test1.Test1.main(Test1.java:49)
  </code></pre>
  
  <p>I'm sure there's a way to do this using my <code>XmlAdapter</code>-based code, but I guess I've been staring at this too long to come up with it!</p>