开发者

Marshall object field as attribute

开发者_如何学运维Here is what I have so far to marshall my POJO using JAXB :

@XmlRootElement
public class Local {
    private Entity entity;

    public void setEntity(Entity entity) {
        this.entity = entity;
    }

    @XmlElement
    public Entity getEntity() {
        return entity;
    }
}

and

@XmlRootElement
public class Entity {
    private String name;
    private String comment;

    public void setName(String name){
        this.name = name;
    }

    @XmlAttribute
    public String getName(){
        return this.name;
    }

    public void setComment...

    @XmlAttribute
    public void getComment...
}

With that, I get something like this:

<local>
    <entity name="" comment=""></entity>
</local>

However, I would prefer to have the name attribute as an attribute of the local:

<local entityName="" entityComment=""></local>

Is the XmlJavaTypeAdapter a good way to begin with?

Thanks, Alex


There are a couple of different options to handle this use case:

Option #1 - XmlAdapter (Any JAXB implementation)

You could use an XmlAdapter for this use case. This will work as long as only one attribute value comes from the Entity object:

EntityAdapter

import javax.xml.bind.annotation.adapters.XmlAdapter;

public class EntityAdapter extends XmlAdapter<String, Entity>{

    @Override
    public String marshal(Entity entity) throws Exception {
        if(null == entity) {
            return null;
        }
        return entity.getName();
    }

    @Override
    public Entity unmarshal(String name) throws Exception {
        Entity entity = new Entity();
        entity.setName(name);
        return entity;
    }

}

Local

The XmlAdapter is linked with the field/property using the @XmlJavaTypeAdapter annotation:

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlRootElement
public class Local {
    private Entity entity;

    public void setEntity(Entity entity) {
        this.entity = entity;
    }

    @XmlAttribute
    @XmlJavaTypeAdapter(EntityAdapter.class)
    public Entity getEntity() {
        return entity;
    }

}

For More Information

  • http://blog.bdoughan.com/2010/07/xmladapter-jaxbs-secret-weapon.html
  • http://blog.bdoughan.com/2010/12/jaxb-and-immutable-objects.html

Option #2 - @XmlPath (EclipseLink JAXB (MOXy)

Alternatively if you are using EclipseLink JAXB (MOXy), the you could use the @XmlPath extension. This is useful with the Entity object corresponds to multiple XML attributes:

Local

Specifying the XPath "." indicated that the child contents will be written into the parent element

import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.*;

@XmlRootElement
public class Local {
    private Entity entity;

    public void setEntity(Entity entity) {
        this.entity = entity;
    }

    @XmlPath(".")
    public Entity getEntity() {
        return entity;
    }
}

Entity

public class Entity {
    private String name;
    private String comment;

    public void setName(String name){
        this.name = name;
    }

    @XmlAttribute(name="entityName")
    public String getName(){
        return this.name;
    }

    public void setComment(String comment){
        this.comment = comment;
    }

    @XmlAttribute(name="entityComment")
    public String getComment(){
        return this.comment;
    }
}

For More Information

  • http://bdoughan.blogspot.com/2010/07/xpath-based-mapping.html
  • http://blog.bdoughan.com/2010/09/xpath-based-mapping-geocode-example.html
  • http://blog.bdoughan.com/2011/03/map-to-element-based-on-attribute-value.html
  • http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜