Marshal字段作为具有字段名称的子节点的值属性

时间:2016-01-11 11:45:26

标签: java xml jaxb

一个聪明的人在某处设计了一个像这样的xml:

<node>
  <subnode value="sv1"/>
  <anotherSubNode value="asv" />
</node>

我想将此映射到POJO对象,如下所示:

class Node {
  String subnode;
  String anotherSubNode;
  //...
}

而不是

class NodeValue {
  @XmlAttribute
  String value;
}
class Node {
  NodeValue subnode;
  NodeValue anotherSubNode;
  /...
}

有没有办法可以用标准的java xml编组有效地做到这一点?甚至是非标准的?

1 个答案:

答案 0 :(得分:0)

XmlAdapter是最简单,最通用的解决方案。 String字段的适配器看起来像这样:

public class NodeValueStringAttrMarshaller extends XmlAdapter<NodeValueElement, String> {

    @Override
    public NodeValueElement marshal(String v) throws Exception {
        return new NodeValueElement(v);
    }

    @Override
    public String unmarshal(NodeValueElement v) throws Exception {
        if (v==null) return "";
        return v.getValue();
    }

}

如果您有其他类型的字段,如Long或Boolean,则必须实现其他(同样简单的)适配器。

要编组的通用字段对象也是必要的:

@XmlAccessorType(XmlAccessType.FIELD)
public class NodeValueElement {

    @XmlAttribute(name="value")
    String value;

    public NodeValueElement() {
    }

    public NodeValueElement(String value) {
        super();
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

}

要使用适配器,您必须在POJO中注释相应的字段:

class Node {
  @XmlJavaTypeAdapter(value=NodeValueStringAttrMarshaller.class)
  String subnode;

  @XmlJavaTypeAdapter(value=NodeValueLongAttrMarshaller.class)
  Long anotherSubNode;
  //...
}