JAXB - 如果为false则抑制布尔属性

时间:2011-07-01 20:07:03

标签: java xml jaxb marshalling

假设我有一个班级

@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>

我该怎么做?

非常感谢!

4 个答案:

答案 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;

JAXB beforeMarshal处理程序

@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;