Представление элемента как логического с JAXB? - PullRequest
2 голосов
/ 19 апреля 2010

У нас есть этот XML:

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

<ValueB/> никогда не будет иметь никаких атрибутов или внутренних элементов. Это элемент логического типа - он существует (true) или нет (false).

JAXB сгенерировал класс Summary с элементом String valueA, что хорошо. Но для ValueB JAXB сгенерировал внутренний класс ValueB и соответствующий член:

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

Но я бы хотел boolean член и нет внутренний класс:

@XmlElement(name = "ValueB")
protected boolean valueB;

Как вы можете это сделать?

Я не собираюсь обновлять классы, я бы хотел просто изменить код вручную.


Обновление : в соответствии с принятым ответом мы создали новый метод, возвращающий логическое значение, зависящее от того, является ли valueB == нулевым.

Поскольку мы используем Hibernate, мы аннотировали значение B с помощью @Transient и аннотировали логический метод получения с помощью аннотации @Column в Hibernate.

Ответы [ 2 ]

7 голосов
/ 23 ноября 2010

Использовать 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;
    }
}

И фиктивный объект для сериализации:

package com.example.xml.adaptor;

public class EmptyObject {
    // EMPTY
}

Затем в вашем объекте используйте поле Boolean (не boolean):

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

Это должно создать <isPresent/> элемент, когда true, но опустить его, когда false.

1 голос
/ 19 апреля 2010

Это довольно логично, jaxb создает внутренний класс, так как считает, что это commplexAttribute

Вместо того, чтобы изменить его на логическое значение, вы также можете проверить null == valueB, если вы поставите

@XmlElement(name = "ValueB", nillable='true') protected Summary.ValueB valueB; в твоей логике.

или добавьте дополнительный метод получения, который не имеет @XMl .... и возвращает вычисленное состояние значения B возможно, то, что вы хотите, возможно с JAXB, я не нуждался в этом раньше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...