开发者

Representing element as boolean with JAXB?

开发者 https://www.devze.com 2022-12-27 15:17 出处:网络
We have this XML: <Summary> <ValueA>xxx</ValueA> <ValueB/> </Summary> <ValueB/> will never have any attributes or inner elements.It\'s a boolean type element - i

We have this XML:

  <Summary>
     <ValueA>xxx</ValueA>
     <ValueB/>
  </Summary>

<ValueB/> will never have any attributes or inner elements. It's a boolean type element - it exists (true) or it doesn't (false).

JAXB generated a Summary class with a String valueA member, which is good. But for ValueB, JAXB generated a ValueB inner class and a corresponding member:

@XmlElement(name = "ValueB")
protected Summary.ValueB valueB;

But what I'd like is a boolean member and no inner class:

@XmlElement开发者_JS百科(name = "ValueB")
protected boolean valueB;

How can you do this?

I'm not looking to regenerate the classes, I'd like to just make the code change manually.


Update: In line with the accepted answer, we created a new method returning the boolean value conditional on whether valueB == null.

As we are using Hibernate, we annotated valueB with @Transient and annotated the boolean getter with Hibernate's @Column annotation.


Use an XmlAdaptor:

package com.example.xml.adaptor;
import javax.xml.bind.annotation.adapters.XmlAdapter;

public class BooleanToEmptyObjectAdapter extends XmlAdapter<EmptyObject, Boolean> {
    @Override
    public EmptyObject marshal(final Boolean v) {
        return v != null && v ? new EmptyObject() : null;
    }

    @Override
    public Boolean unmarshal(final EmptyObject v) {
        return true;
    }
}

And a dummy object for it to serialize:

package com.example.xml.adaptor;

public class EmptyObject {
    // EMPTY
}

Then in your object, use a Boolean (not a boolean) field:

@XmlRootElement(name = "FooElement")
public class Foo {

    @XmlElement()
    @XmlJavaTypeAdapter(BooleanToEmptyObjectAdapter.class)
    private final Boolean isPresent = false;

    ...
    // You might need to @XmlTransient your getter/setter, or JAXB might complain about redefinition
    @XmlTransient
    public boolean isPresent() {
        return this.isPresent;
    }
}

This should produce <isPresent/> element when true, but omit it when false.


It's quite logic jaxb creates an inner class as it thinks that is a commplexAttribute

Instead of changing it to a boolean you could also check null == valueB if you put

@XmlElement(name = "ValueB", nillable='true') protected Summary.ValueB valueB; in your logic.

or add an extra getter that does not have @XMl.... and returns computed state of valueB perhaps what you want is possible with JAXB I have not needed it before.

0

精彩评论

暂无评论...
验证码 换一张
取 消