Jaxb Unmarshall返回null

时间:2019-05-21 02:52:25

标签: java xml jaxb unmarshalling

我正在尝试通过jaxb解组xml文件。

我的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>

***重要 键值的内容可以是任何类型(字符串,日期,整数)。

我要解组元素的代码:

@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 :(得分:0)

更改较少以做您想要的(我能想到的)的方法如下。

创建一个看起来像这样的类:

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

它将完成工作。