Marshall对象字段作为属性 [英] Marshall object field as attribute
问题描述
到目前为止,我使用JAXB对我的POJO进行编组:
@XmlRootElement
public class Local {
私人实体实体;
public void setEntity(实体实体){
this.entity = entity;
}
@XmlElement
public Entity getEntity(){
return entity;
}
}
和
@XmlRootElement
public class Entity {
private String name;
私人字符串评论;
public void setName(String name){
this.name = name;
}
@XmlAttribute
public String getName(){
return this.name;
}
public void setComment ...
@XmlAttribute
public void getComment ...
}
有了这个,我得到这样的结果:
<局部>
< entity name =comment =>< / entity>
< / local>
但是,我更希望将name属性作为本地属性:
< local entityName =entityComment =>< / local>
XmlJavaTypeAdapter是一个好的开始方式吗?
谢谢,
Alex
有几种不同的选项可以处理这个用例: / p>
选项#1 - XmlAdapter(任何JAXB实现)
您可以使用此用例的 XmlAdapter
。只要只有一个属性值来自实体
对象,这将有效:
EntityAdapter
import javax.xml.bind.annotation.adapters.XmlAdapter;
公共类EntityAdapter扩展XmlAdapter< String,Entity> {
@Override
public String marshal(Entity entity)抛出异常{
if(null == entity){
返回null;
}
返回entity.getName();
}
@Override
public Entity unmarshal(String name)throws Exception {
Entity entity = new Entity();
entity.setName(name);
返回实体;
}
}
本地
使用 @XmlJavaTypeAdapter
注释将XmlAdapter与字段/属性链接:
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(实体实体){
this.entity = entity;
}
@XmlAttribute
@XmlJavaTypeAdapter(EntityAdapter.class)
public Entity getEntity(){
return entity;
}
}
For更多信息
- http://blog.bdoughan.com/2010/07/xmladapter-jaxbs-secret-weapon.html
- http://blog.bdoughan.com/ 2010/12 / jaxb-and-immutable-objects.html
选项#2 - @XmlPath(EclipseLink JAXB(MOXy)
或者,如果您使用 EclipseLink JAXB(MOXy) ,您可以使用 @XmlPath
extension。这对于 Entity
对象有用,对应多个XML属性:
本地
指定XPath。表示将子内容写入父元素
import javax.xml.bind.annotation。*;
import org.eclipse.persistence.oxm.annotations。*;
@XmlRootElement
public class Local {
private Entity entity;
public void setEntity(实体实体){
this.entity = entity;
}
@XmlPath(。)
public Entity getEntity(){
return entity;
}
}
实体
public class Entity {
private String name;
私人字符串评论;
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;
}
}
更多信息
- 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
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
这篇关于Marshall对象字段作为属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!