Jaxb unmarshall возвращается ноль - PullRequest
0 голосов
/ 21 мая 2019

Я пытаюсь разобрать xml-файл через jaxb.

Мой xml-файл:

<root id="1">
   <fields>
      <field id="2">
         <values>
            <value><some></value>
         </values>
      </field>
      <field id="3">
         <values>
            <value><xxx></value>
         </values>
      </field>
     <field id="483">
         <values />
      </field>
     </fields>
</root>

*** Внимание! Содержимое значения ключа может быть любого типа(string, date, int).

Мой код для отмены маршалинга элементов:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Fields", propOrder = {
    "cuestionarios"
})
@XmlRootElement(name = "root")
public class Fields {
    @XmlElement(name = "fields", required = true)
    protected Field cuestionarios;

    public Field getCuestionarios() {
        return cuestionarios;
    }

    public void setCuestionarios(Field cuestionarios) {
        this.cuestionarios = cuestionarios;
    }
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Field", propOrder = {
    "values"
})
public class Field {
    @XmlElement(name = "field", required = true)
    protected List<Value> values;

    public List<Value> getValues() {
        if (values == null) {
        values = new ArrayList<>();
    }
    return this.values;
    }
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Value", propOrder = {
    "value"
})
public class Value {
    @XmlElement(name = "values", required = true)
    protected List<Object> value;

    public Value(){

    }

    public List<Object> getValue() {
        if (value == null) {
        value = new ArrayList<>();
    }
    return this.value;
    }

    public void setValue(List<Object> value) {
        this.value = value;
    }

Я получаю нулевые значения в cuestionarios.Я не уверен, что это ошибка в XML, она плохо отформатирована или у меня есть некоторые ошибки в тегах XML.Я думаю, что ошибка в метках XML.Список заполнен, но все его поля пусты.

Спасибо.

1 Ответ

0 голосов
/ 21 мая 2019

Путь с меньшими изменениями, чтобы делать то, что вы хотите (о чем я могу думать), описан ниже.

Создайте класс, который выглядит следующим образом:

@XmlAccessorType(XmlAccessType.FIELD)
public class ValueContent {

    @XmlElement(name = "value")
    private String content;
}

и адаптируйтеваш класс Value, чтобы использовать его вместо Object, например:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Value", propOrder = {
        "value"
})
public class Value {
    @XmlElement(name = "values", required = true)
    protected List<ValueContent> value;

    public Value(){

    }

    public List<ValueContent> getValue() {
        if (value == null) {
            value = new ArrayList<>();
        }
        return this.value;
    }

    public void setValue(List<ValueContent> value) {
        this.value = value;
    }
}

Изменить для ответа на комментарий:

В этом случае вы можете сделать что-то подобное:

@XmlAccessorType(XmlAccessType.FIELD)
public class ValueContent {

    @XmlElements({
            @XmlElement(name = "text", type = String.class),
            @XmlElement(name = "number", type = Integer.class)
    })
    private Object content;
}

Но тогда вам, xml, придется использовать другую метку, основанную на типе, как показано ниже:

<root id="1">
    <fields>
        <field id="2">
            <values>
                <number>1</number>
            </values>
        </field>
        <field id="3">
            <values>
                <text>value1</text>
            </values>
        </field>
    </fields>
</root>

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

Другим вариантом (недоделанная мысль) будет использование адаптера для этого поля и попытка получить тип ввода и правильно его привести.

Отредактируйте 2, чтобы показать использование адаптера: Вы можете создать адаптер, как показано ниже:

public class CastingAdapter extends XmlAdapter<String, Object> {

    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

    @Override
    public String marshal(Object arg0) throws Exception {
        return null;
    }

    @Override
    public Object unmarshal(String arg0) throws Exception {
        if(StringUtils.isNumeric(arg0)) {
            return Integer.valueOf(arg0);
        }

        if(StringUtils.isAlphanumeric(arg0)) {
            return arg0;
        }

        if(isValidDate(arg0)) {
            return dateFormat.parse(arg0);
        }

        return arg0;
    }

    private boolean isValidDate(String inDate) {

        dateFormat.setLenient(false);
        try {
            dateFormat.parse(inDate.trim());
        } catch (ParseException pe) {
            return false;
        }
        return true;
    }
}

И использовать этот адаптер в ValueContent:

@XmlAccessorType(XmlAccessType.FIELD)
public class ValueContent {

    @XmlJavaTypeAdapter(CastingAdapter.class)
    private Object value;
}

Для XML, как показано ниже:

<root id="1">
    <fields>
        <field id="1">
            <values>
                <value>2009-12-31</value>
            </values>
        </field>
        <field id="2">
            <values>
                <value>1</value>
            </values>
        </field>
        <field id="3">
            <values>
                <value>value1</value>
            </values>
        </field>
    </fields>
</root>

Itсделал бы работу.

...