![](/img/trans.png)
[英]Passing empty string to .tag with a java.lang.Integer attribute results in 0 (not null)
[英]Casting null java.lang.Integer from JAXB produces 0, not null
我有以下XML:
<person>
<id/>
<Identifier/>
<Surname>TEST</Surname>
<Forename1>TEST</Forename1>
<Forename2/>
<Title>MR</Title>
<Gender>M</Gender>
</person>
通过序列化以下类产生:
package anonymised.packagename;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"Id",
"Identifier",
"Surname",
"Forename1",
"Forename2",
"Title",
"Sex"
})
@XmlRootElement(name = "person")
public class person{
@XmlElement(name = "id", nillable=true)
protected Integer Id;
public Integer getId(){
return Id;
}
public void setId(Integer value){
this.Id = value;
}
@XmlElement(name = "Identifier", nillable=true)
protected String Identifier;
public String getIdentifier(){
return Identifier;
}
public void setIdentifier(String value){
this.Identifier = value;
}
@XmlElement(name = "Surname", nillable=true)
protected String Surname;
public String getSurname(){
return Surname;
}
public void setSurname(String value){
this.Surname = value;
}
@XmlElement(name = "Forename1", nillable=true)
protected String Forename1;
public String getForename1(){
return Forename1;
}
public void setForename1(String value){
this.Forename1 = value;
}
@XmlElement(name = "Forename2", nillable=true)
protected String Forename2;
public String getForename2(){
return Forename2;
}
public void setForename2(String value){
this.Forename2 = value;
}
@XmlElement(name = "Title", nillable=true)
protected String Title;
public String getTitle(){
return Title;
}
public void setTitle(String value){
this.Title = value;
}
@XmlElement(name = "Gender", nillable=true)
protected String Gender;
public String getGender(){
return Gender;
}
public void setGender(String value){
this.Gender = value;
}
}
我使用对象上的“设置”方法和JAXB序列化生成上面的XML,正是由于它们是可空的,因此选择java.lang.Integer对象。
然后,我使用以下代码将XML(由xmlString表示)反序列化回该对象:
DocumentBuilder builder = fac.newDocumentBuilder();
Document doc = builder.parse(new InputSource(new StringReader(xmlString)));
String className = "anonymised.packagename." + doc.getDocumentElement().getNodeName();
Class<?> c = Class.forName(className);
JAXBContext context = JAXBContext.newInstance(c);
Unmarshaller um = context.createUnmarshaller();
Object o = c.cast(um.unmarshal(new StringReader(xmlString)));
JAXBContext jbc = JAXBContext.newInstance(c);
Marshaller jm = jbc.createMarshaller();
jm.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jm.marshal(o, new File("C:\\person.xml"));
产生了以下XML文件:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<person>
<id>0</id>
<Identifier/>
<Surname>TEST</Surname>
<Forename1>TEST</Forename1>
<Forename2></Forename2>
<Title>MR</Title>
<Gender>M</Gender>
</person>
现在为null的java.lang.Integer为0。这怎么可能? 从断点来看,在转换过程中会发生从null到0的更改,但是我不知道为什么会这样。 在转换过程中是否有某种转换为简单int的方法? 有办法避免这种现象吗? 我认为在XML Element声明中添加“ nillable”会有所帮助,但没有帮助。
JAXB认为任何空元素都不是null
的有效表示形式。 如果您indentifier
String
类型的indentifier
属性进行内省,则在解组空元素后会看到它是""
。
null的两个有效表示形式是:
minOccurs="0"
。 这是默认行为。 xsi:nil="true"
。 这对应于XML架构中的nillable="true"
。 如果使用@XmlElement(nillable=true)
注释属性,则将获得此行为。 感谢您的回答。 在第2点上,我在上面的类中用@XmlElement(nillable = true)注释了我的属性,但是我没有您在XML中描述的行为。 您的答案是否意味着在生成任何应该为null的XML时,需要将属性xsi:nil显式设置为true?
当您拥有@XmlElement(nillable=true)
,期望的是相应的XML元素将xsi:nil
属性设置为true
,如下所示:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<person>
<id xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
</person>
我对Identifier元素是一个空String而不是null而是id元素的想法感到满意,因为它是一个Integer应该为null而不是0,对吧?
您绝对可以提出该论点。 使用JAXB RI,如果将Integer
属性更改为Long
您将看到所需的行为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.