假设我有一个班级
@XmlRootElement(name="thing")
public class Thing{
private String name;
private boolean awesome;
@XmlValue public void setName(String name) {
this.name = name;
}
public String getName() {
return this.value;
}
@XmlAttribute public void setAwesome(boolean awesome) {
this.awesome = awesome;
}
public boolean isAwesome() {
return this.awesome;
}
}
如果我创建了一些东西,然后将它们编组为XML,它看起来像这样:
飞行忍者:
<thing awesome="true">flying ninja</thing>
一个普通的爆米花球:
<thing awesome="false">popcorn ball</thing>
但是......我想要做的是改变我的布尔属性编组的方式。我宁愿看到爆米花球看起来像这样,压抑了令人敬畏的属性:
<thing>popcorn ball</thing>
我该怎么做?
非常感谢!
答案 0 :(得分:8)
注意:我是EclipseLink JAXB (MOXy)负责人,也是JAXB 2.X(JSR-222)专家组的成员。
使用MOXy,您可以按Hovercraft Full Of Eels的建议执行XmlAdapter
方法。它看起来像是:
BooleanAdapter
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class BooleanAdapter extends XmlAdapter<Boolean, Boolean> {
@Override
public Boolean unmarshal(Boolean v) throws Exception {
return Boolean.TRUE.equals(v);
}
@Override
public Boolean marshal(Boolean v) throws Exception {
if(v) {
return v;
}
return null;
}
}
<强>事强>
您使用XmlAdapter
注释将您的媒体资源与@XmlJavaTypeAdapter
相关联,如下所示:
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlValue;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlRootElement(name="thing")
public class Thing{
private String name;
private boolean awesome;
@XmlValue public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
@XmlAttribute
@XmlJavaTypeAdapter(BooleanAdapter.class)
public void setAwesome(boolean awesome) {
this.awesome = awesome;
}
public boolean isAwesome() {
return this.awesome;
}
}
<强>演示强>
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Thing.class);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
Thing thing = new Thing();
thing.setName("popcorn ball");
thing.setAwesome(false);
marshaller.marshal(thing, System.out);
thing.setAwesome(true);
marshaller.marshal(thing, System.out);
}
}
<强>输出强>
<?xml version="1.0" encoding="UTF-8"?>
<thing>popcorn ball</thing>
<?xml version="1.0" encoding="UTF-8"?>
<thing awesome="true">popcorn ball</thing>
使用JAXB RI
如果使用JAXB RI运行此示例,则会出现以下异常:
Exception in thread "main" com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
Adapter example.BooleanAdapter is not applicable to the field type boolean.
this problem is related to the following location:
at @javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter(type=class javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter$DEFAULT, value=class example.BooleanAdapter)
at public boolean example.Thing.isAwesome()
at forum251.Thing
了解更多信息
答案 1 :(得分:2)
通过使用可空类型并向您的类注册JAXB侦听器来实现此目的。在JAXB侦听器中,如果您不想编组它,请将属性设置为null
。这种方法应该适用于任何JAXB实现。
@XmlAttribute(required = false)
private Boolean valueUnknown;
@SuppressWarnings("PMD")
private void beforeMarshal(final Marshaller marshaller) {
// Remove the "valueUnknown" attribute if it is not true.
// Assigning a null value implies that the attribute is removed.
if(!valueUnknown) {
valueUnknown = null;
}
}
这种方法可以 - 例如 - 产生下面的结果。请注意,仅当没有给出value属性时,才会出现属性valueUnknown。
<items>
<item xsi:type="eduDataExchange:compoundValue" valueUnknown="true"/>
<item xsi:type="eduDataExchange:compoundValue" value="4" percentage="3"/>
</items>
答案 2 :(得分:1)
我还不熟悉JAXB(但是),但通常这类事情应该对XSLT processing或转换很有用。
此外,这个问题的答案提到使用XmlAdapter,它看起来直接适用于您的问题:How to let JAXB render boolean as 0 and 1, not true and false
答案 3 :(得分:0)
用布尔对象替换布尔值,它为我解决了这个问题。
使用: -
private Boolean awesome;
而不是: -
private boolean awesome;