Home  >  Article  >  Java  >  How to Marshall a Map into `value` XML Structure with JAXB?

How to Marshall a Map into `value` XML Structure with JAXB?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-11-18 02:48:02851browse

How to Marshall a Map into `value` XML Structure with JAXB?

JAXB: Marshalling Map into value

While JAXB natively supports marshalling a Map into XML structures like:

<map>
  <entry>
    <key> KEY </key>
    <value> VALUE </value>
  </entry>
  <entry>
    <key> KEY2 </key>
    <value> VALUE2 </value>
  </entry>
  ...
</map>

You may require an XML structure where the key is the element name and the value is its content:

<map>
  <key> VALUE </key>
  <key2> VALUE2 </key2>
 ...
</map>

Recommendation against Custom XML Structure

Generating XML with dynamic element names is generally discouraged. XML schemas (XSDs) define interface contracts. JAXB can generate XSDs from code, allowing you to restrict exchanged data according to predefined structures in XSDs.

In the default case, a Map will generate an XSD restricting map elements to contain xs:string keys and values. This ensures a clear interface contract.

Your approach would generate an XSD specifying that the map contains elements with unknown types, which violates good practice.

Enum Key Solution

To enforce a strict contract, consider using an enumerated type as the map key instead of a String:

public enum KeyType {
    KEY, KEY2;
}

@XmlJavaTypeAdapter(MapAdapter.class)
Map<KeyType, String> mapProperty;

JAXB will generate a schema restricting map elements to elements using the predefined keys KEY or KEY2.

Simplification of Default Structure

If you prefer the simpler XML structure of elements, you can use a MapAdapter that converts the Map to an array of MapElements:

class MapElements {
    @XmlAttribute public String key;
    @XmlAttribute public String value;
}

class MapAdapter extends XmlAdapter<MapElements[], Map<String, String>> {
    public MapElements[] marshal(Map<String, String> arg0) {
        MapElements[] mapElements = new MapElements[arg0.size()];
        int i = 0;
        for (var entry : arg0.entrySet())
            mapElements[i++] = new MapElements(entry.getKey(), entry.getValue());
        return mapElements;
    }
    public Map<String, String> unmarshal(MapElements[] arg0) {
        Map<String, String> r = new TreeMap<>();
        for (MapElements mapelement : arg0)
            r.put(mapelement.key, mapelement.value);
        return r;
    }
}

The above is the detailed content of How to Marshall a Map into `value` XML Structure with JAXB?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn