boris
boris

Reputation: 59

Jaxb Complex Marshal element

I have an complex XML which I need to build java objects from. I doing it using Unmarshal. while this work perfect I'm also need to print the Java object as String. I have two solutions for this :

  1. implement the toString() method for each of the nested classes. -> this works fine
  2. implememt marshal. -> having errors here.

I having this XML :

<Lang>
        <a1 NAM="Momo" RTA="" />
        <a2 NAM="Rena" RTA="buba" />
        <a3 NAM="Fiba" RTA="kusit" />
        <a4 NAM="Shila" RTA="hamuda" />
<Lang>  

I needed to generate map representation of java object.

Map - Key is the first attribute in this example a1,a2,a3...

Map - value is the rest of the attributes - for this i implemented class that have the attribute NAM and RTA , class name is BBB.

In this class i build a constructor that has 1 parameter - Element.

I'm Calling this construtor from the Unmarshall method

I don't now the numbers of values in the map.

i don't now the name of the attribute - a1 , a2 .. need to be generic

So , What I'v done to do the unmarshall correctly is :

  1. I build a class the contains List of Elememt (org.w3c.dom.Element) -with the @XmlAnyElement annotation. class name is ABC

  2. I build a class that extends the XmlAdapter{ABC, MAP{String,BBB}}

    and implemented the Unmarshall method and NOT implemet to Marshall method

This works fine, I getting the data exactly how i expected it to be. Now I want to implement the Marshal method and don't sure about to do it because element is not a regular object - it is an interface.

The Marshal method:

@Override
public LangVos marshal(Map<String, BBB> map) {
    ABC abc = new ABC();
    langVos.langVOs = new ArrayList<Element>(map.size());
    for (Entry<String, BBB> entry : map.entrySet()) {

        Element e = (Element) entry.getValue(); // how to create Element using factory from entry ?
        ABC.list.add(e); 
    }
    return abc;
}

I don't now how to set the attributes in the marshall. While in the unmarshal I needed to do getAttribute.

I Hope I'm being clear.

Thanks for any help.

Boris.

Upvotes: 2

Views: 1908

Answers (1)

bdoughan
bdoughan

Reputation: 149027

For the marshal, you should be able to accomplish what you need by creating JAXBElements that wrap instances of BBB:

package forum7219883;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.namespace.QName;

import org.w3c.dom.Element;

public class MapAdapter extends XmlAdapter<AdaptedMap, Map<String, BBB>>{

    @Override
    public AdaptedMap marshal(Map<String, BBB> map) throws Exception {
        AdaptedMap adaptedMap = new AdaptedMap();
        for(Entry<String, BBB> entry : map.entrySet()) {
            adaptedMap.entry.add(new JAXBElement<BBB>(new QName(entry.getKey()), BBB.class, entry.getValue()));
        }
        return adaptedMap;
    }

    @Override
    public Map<String, BBB> unmarshal(AdaptedMap arg0) throws Exception {
        int entrySize = arg0.entry.size();
        Map<String, BBB> map = new HashMap<String, BBB>(entrySize);
        for(int x=0; x<entrySize; x++) {
            Element element = (Element) arg0.entry.get(x);
            BBB bbb = new BBB();
            bbb.setNam(element.getAttribute("NAM"));
            bbb.setRta(element.getAttribute("RTA"));
            map.put(element.getLocalName(), bbb);
        }
        return map;
    }

}

Upvotes: 0

Related Questions