1

我有关于将 XML 转换为 Java 对象的问题,在这里我使用 JAXB。
就我而言:

XML 数据:

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

XML 数据的 JAVA 类:

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();

它将给出结果:人名=“Aris Tonar”
人年龄=空
人昵称=“”
人ID=空
人萨尔多=空

但不是我想要的结果,我希望 JAXB 会给出结果:

人名 = "Aris Tonar"
人年龄 = 0
人昵称 = ""
人 id = null
人萨尔多 = 0

  1. 我希望在 XML DATA 中声明的每个元素都将:如果它的值指定 jaxb 会将其解释为正常值(如 name 元素)但如果它的值未指定 jaxb 将其解释为默认值(如年龄、昵称、saldo 元素)
  2. 如果元素未在 XML 数据中声明,则 jaxb 会将其解释为 null。(如 id 元素)

我是否可以这样做?可能与自定义 JAXBContext 代码有关?

4

4 回答 4

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,指定但为空的元素表示空字符串,请记住,在 XML<nickname />中完全等同于<nickname></nickname>.

于 2012-08-16T10:55:00.087 回答
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;
}


}
于 2012-08-16T11:12:30.883 回答
1

如果在声明成员时使用默认值实例化成员,则应该解决第一个问题。

尝试:

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

hth,
麦克莱克斯

于 2012-08-16T10:00:18.267 回答
0

我你使用 cxf-codegen-plugin,你可以(从 XSD/WSDL 开始)

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

例如,这将为您的字段年龄创建一个吸气剂,如下所示:

public Integer getAge() {
   if (age == null)
      return new Interger(0);
   return age;
}
于 2012-08-16T10:08:21.087 回答