DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Newsletter
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • SmartXML: An Alternative to XPath for Complex XML Files
  • Validate XML Request Against XML Schema in Mule 4
  • How to Convert JSON to RAML
  • How to Convert JSON to XML or XML to JSON in Java

Trending

  • Running a Self-Hosted WAF in Production: Practical Lessons From SafeLine
  • The SDLC After AI
  • Adding Graph Retrieval to a RAG Pipeline With Python
  • Build a Voice Assistant With Gemini Live API

Draft This article hasn't been published, so readers can't see it.

In moderation This article is waiting for review, so readers can't see it yet.

Deleted This article has been deleted, so readers can't see it.

  1. DZone
  2. Coding
  3. Languages
  4. MOXy's @XmlVariableNode - Using a Map's Key as the Node Name

MOXy's @XmlVariableNode - Using a Map's Key as the Node Name

By 
Blaise Doughan
·
Jun. 20, 13 · Interview
Post on X (opens in a new tab) Share on LinkedIn (opens in a new tab)
13.3K Views

Join the DZone community Save articles, join the discussion, and download Refcards and Trend Reports with a free account.

Join for free Already a member? Log in
People often ask me how they can map a java.util.Map such that the keys become the node names.  In this post I will demonstrate how this can be done using the new Variable Node mapping that we have added in EclipseLink MOXy.

You can try this out today using a nightly build of EclipseLink 2.6.0:
  • http://www.eclipse.org/eclipselink/downloads/nightly.php

Input/Output

Below are the XML and JSON representations we will use in this example.  Each has node names that correspond to keys and contents that correspond to values of a Map.

XML (input.xml)

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <A>1</A>
   <B>2</B>
</root>
JSON (Output)

{
   "A" : 1,
   "B" : 2
}

Java Model (Root)
We want a non-default XML (and JSON) representation for Map so we will use an XmlAdapter (see: JAXB and java.util.Map).  MOXy's @XmlPath extension will be used to prevent the contents of the adapted Map from being wrapped in a parent element (see: XPath Based Mapping).
package blog.variablenode.map;
 
import java.util.*;
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.eclipse.persistence.oxm.annotations.XmlPath;
 
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {
 
    @XmlPath(".")
    @XmlJavaTypeAdapter(MapAdapter.class)
    private Map<String, Integer> map = new HashMap<String, Integer>();
 
}
XmlAdapter (MapAdapter) 
An XmlAdapter is used to convert an object for the purposes of marshalling/unmarshalling (see: XmlAdapter - JAXB's Secret Weapon).  In this example we convert the Map to an AdaptedMap that has a List of AdaptedEntry values.  These AdaptedEntry values have a field (key) to represent the key.  It is this field that we will use with @XmlVariableNode (line 13).  We will mark the key field with @XmlTransient to prevent if from being marshalled/unmarshalled (line 20).

package blog.variablenode.map;
 
import java.util.*;
import java.util.Map.Entry;
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import org.eclipse.persistence.oxm.annotations.XmlVariableNode;
 
public class MapAdapter extends XmlAdapter<MapAdapter.AdaptedMap, Map<String, Integer>> {
 
    public static class AdaptedMap {
         
        @XmlVariableNode("key")
        List<AdaptedEntry> entries = new ArrayList<AdaptedEntry>();
         
    }
 
    public static class AdaptedEntry {
         
        @XmlTransient
        public String key;
         
        @XmlValue
        public Integer value;
 
    }
 
    @Override
    public AdaptedMap marshal(Map<String, Integer> map) throws Exception {
        AdaptedMap adaptedMap = new AdaptedMap();
        for(Entry<String, Integer> entry : map.entrySet()) {
            AdaptedEntry adaptedEntry = new AdaptedEntry();
            adaptedEntry.key = entry.getKey();
            adaptedEntry.value = entry.getValue();
            adaptedMap.entries.add(adaptedEntry);
        }
        return adaptedMap;
    }
 
    @Override
    public Map<String, Integer> unmarshal(AdaptedMap adaptedMap) throws Exception {
        List<AdaptedEntry> adaptedEntries = adaptedMap.entries;
        Map<String, Integer> map = new HashMap<String, Integer>(adaptedEntries.size());
        for(AdaptedEntry adaptedEntry : adaptedEntries) {
            map.put(adaptedEntry.key, adaptedEntry.value);
        }
        return map;
    }
 
}
Demo
Below is some demo code that can be run to prove that everything works.  The Root object will be instantiated from XML input and marshalled to create the JSON output.

package blog.variablenode.map;
 
import java.io.File;
import javax.xml.bind.*;
 
import org.eclipse.persistence.jaxb.MarshallerProperties;
 
public class Demo {
 
    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Root.class);
         
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/blog/variablenode/map/input.xml");
        Root root = (Root) unmarshaller.unmarshal(xml);
         
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/json");
        marshaller.setProperty(MarshallerProperties.JSON_INCLUDE_ROOT, false);
        marshaller.marshal(root, System.out);
    }
 
}
Further Reading
If you enjoyed this post then you may also be interested in:
  • MOXy's @XmlVariableNode - JSON Schema Example
  • Specifying EclipseLink MOXy as your JAXB Provider
  • JAXB and java.util.Map
  • JSON Binding with EclipseLink MOXy - Twitter Example

JSON EclipseLink XML Convert (command) POST (HTTP) Object (computer science) Schema XPath

Published at DZone with permission of Blaise Doughan. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • SmartXML: An Alternative to XPath for Complex XML Files
  • Validate XML Request Against XML Schema in Mule 4
  • How to Convert JSON to RAML
  • How to Convert JSON to XML or XML to JSON in Java

Partner Resources

×

Comments

Loading comments

The comments didn't load

Please try again in a moment.

Likes

Loading

The next likes didn't load. Please try again.

The likes didn't load

Please try again in a moment.

See who liked this

Log in or join DZone for free to see who liked this article.

Log in Join for free
  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook