2012-08-16 137 views
1

我有关于将XML转换为Java对象的问题,在这里我使用JAXB。
在我的情况:如何自定义JAXBContext Unmarshaller复杂的情况下

XML数据:XML数据的

<persons> 
    <person> 
    <name>Aris Tonar</name> 
    <age /> 
    <nickname /> 
    <saldo /> 
    </person> 
</persons> 

JAVA CLASS:

public class Person{ 
    private String name; 
    private Integer age; 
    private String nickName; 
    private Integer id; 
    private Double saldo; 

    /** 
    *Setter and Getter 
    */ 

} 

,当我使用标准的JAXBContext Unmarshaller的代码,它解析为Java对象。与代码:

JAXBContext context = JAXBContext.newInstance(Person.class.getPackage().getName()); 
Unmarshaller unmarshaller = context.createUnmarshaller(); 
JAXBElement element = (JAXBElement) unmarshaller.unmarshal(new StreamSource(new StringReader(stringOfXmlData.toString()))); 
Person obj = (Person) element.getValue(); 

它会给结果: 人名= “阿里斯Tonar”
人年龄= NULL
人昵称= “”
人物ID = NULL
人saldo = NULL

但不是那个结果我想要的,我想JAXB会给出结果:

Person name =“Aris Tonar”
人年龄= 0
人昵称= “”
人物ID = NULL
人saldo = 0

  1. 我想这在XML数据中声明的每一个元素会:它是否值指定JAXB会解释它是正常的(如名称元素),但如果它的值没有指定jaxb会将其解释为默认值(如年龄,昵称,saldo元素)
  2. 如果元素未在XML数据中声明,则jaxb会将其解释为null。 (如id元素)

是否有可能我做了吗?可能会自定义JAXBContext代码?

回答

3
@XmlType(name = "person", propOrder = {"name", "age", "nickName" , "saldo"}) 
public class Person { 

private String name; 
private Integer age; 
private String nickName; 
private Integer id; 
private Double saldo; 

public Person(String name, Integer age, String nickName, Integer id, Double saldo) { 
    this.name = name; 
    this.age = age; 
    this.nickName = nickName; 
    this.id = id; 
    this.saldo = saldo; 
} 

public Person() { 
    //jaxb constructor 
} 

@XmlElement(defaultValue="0") 
public Integer getAge() { 
    return age; 
} 

@XmlTransient 
public Integer getId() { 
    return id; 
} 

@XmlElement(defaultValue="") 
public String getName() { 
    return name; 
} 

@XmlElement(name="nickname" , defaultValue="") 
public String getNickName() { 
return nickName; 
} 

@XmlElement(defaultValue="0") 
public Double getSaldo() { 
    return saldo; 
} 

public void setAge(Integer age) { 
    this.age = age; 
} 

public void setId(Integer id) { 
    this.id = id; 
} 

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

public void setNickName(String nickName) { 
    this.nickName = nickName; 
} 

public void setSaldo(Double saldo) { 
    this.saldo = saldo; 
} 


} 
+0

+1 - 你说得对。 – 2012-08-16 11:44:18

+0

非常感谢Err,你的解释是我的解决方案,, – 2012-08-18 09:09:29

+0

hallo Err,我有其他问题.. 我的Java类,它也是该类中的xml注释是来自xsd文件的JAXB Binding的结果,在我的情况下JAXB Binding define '@XmlAttribute'属性,所以我如何为该属性分配defaultValue。 谢谢 – 2012-08-19 07:33:53

1

如果您在声明它们时用默认值实例化成员,则应该修复第一个问题。

尝试:

public class Person{ 
private String name = ""; 
private Integer age = 0; 
private String nickName; = "" 
private Integer id = 0; 
private Double saldo =0.0; 

心连心,
mcalex

0

我使用CXF-CODEGEN-插件,你可以(从XSD/WSDL开始)

  1. 设置的默认您的数据模型的XSD中的值(每种类型的“默认”关键字)
  2. 使用cxf-xjc-dv扩展名lugin处理生成类的getter中的默认值。

这将为实例创建一个getter你的年龄字段是这样的:

public Integer getAge() { 
    if (age == null) 
     return new Interger(0); 
    return age; 
} 
+0

这是任择议定书想要什么,但相反的,因为这将返回默认值是在XML和空字符串/空值_are_指定的元素_not_规定,但有一个空值的元素。 OP希望指定但空的 - >默认和未指定 - >'null'。 – 2012-08-16 10:11:32

3

这是有点麻烦,但你应该能够达到你想要使用类型的适配器什么:

public class Person{ 
    private String name; 
    @XmlJavaTypeAdapter(IntegerZeroDefaultAdapter.class) 
    @XmlSchemaType(name = "integer") 
    private Integer age; 
    private String nickName; 
    private Integer id; 
    @XmlJavaTypeAdapter(DoubleZeroDefaultAdapter.class) 
    @XmlSchemaType(name = "double") 
    private Double saldo; 
    // ...  
} 

public class IntegerZeroDefaultAdapter extends XmlAdapter<String, Integer> { 
    public String marshal(Integer n) { 
    return String.valueOf(n); 
    } 

    public Integer unmarshal(String val) { 
    if(val == null) return null; 
    else if("".equals(val)) return 0; 
    else return Integer.valueOf(val); 
    } 
} 

// likewise for DoubleZeroDefaultAdapter 

除非您要使用的默认值不是空字符串,否则您不需要适配器名称或昵称 - 字符串值的默认值是缺少的元素表示null和指定的bu t-empty元素表示空字符串,请记住在XML中<nickname />完全等同于<nickname></nickname>

+0

尽管在重新阅读文档时,我会说Err的回答使用@XmlElement(defaultValue =“...”)是更好的解决方案。 – 2012-08-16 14:14:33

+0

感谢Ian Roberts,尽管Err的回答更简单,但是您的解释是我处理复杂元素(如java.util.Date或其他不包装类(Custom Class))的解决方案。 – 2012-08-18 09:13:29

相关问题