使用jaxb将自定义xml映射到java包括inheritence和hashmap

时间:2017-09-26 09:12:28

标签: java xml jaxb

我有xml喜欢

taskkill /F /FI "WindowTitle eq  LOOP" /T

我们有类似Protocol1,Protocol2..etc的类派生自基类Protocol。像

<Data>
<Protocol1
    var1="aaa"
    var2="bbb"
/>
<Protocol2
    var3="vv"
    var4="ff"
/>
</Data>

类数据可以包含列表或协议映射。对于map键,将像“Protocol1”,值将是Protocol1类的对象。

@XmlRootElement(name="Protocol1")
class Protocol1 extends Protocol
{
    @XmlAttribute
    String var1;

    @XmlAttribute
    String var2;
}
class Protocol
{
}

我尝试过http://blog.bdoughan.com/2013/06/moxys-xmlvariablenode-using-maps-key-as.html,但没有成功。 如何将变量节点和继承一起用于非编组。请指导。 目前的代码是:

@XmlRootElement(name="Data")
class Data
{
    @XmlJavaTypeAdapter(MapAdapter.class)
   Map<String,Protocol> protocolMap;
}

1 个答案:

答案 0 :(得分:0)

根据您的JAXB实施,您有两个问题的解决方案:

  
      
  1. 使用参考JAXB实现
  2.   

使用参考实现,您可以执行以下操作:

XmlAdapter<List<Protocol>,Map<String,Protocol>>

您的适配器应扩展public class MapAdapter extends XmlAdapter<List<Protocol>,Map<String,Protocol>>{ @Override public List<Protocol> marshal(Map<String,Protocol> map){ return new ArrayList<Protocol>(map.values()); } @Override public Map<String,Protocol> unmarshal(List<Protocol> lst){ Map<String,Protocol> map = new HashMap<>(); for(Protocol p : lst){ map.put(p.getClass().getSimpleName(),p); } return map; } }

@XmlElements

此解决方案的问题是您必须在@XmlRootElement(name="Data") class Data { @XmlJavaTypeAdapter(MapAdapter.class) @XmlPath(".") Map<String,Protocol> protocolMap; } 注释中列出每个扩展类。

  
      
  1. 使用EclipseLink MoXY JAXB实现
  2.   

Blaise Doughan的示例使用自定义JAXB实现,如果您愿意使用它,可以使用以下解决方案:

@XmlPath(".")

请注意,当您同时使用@XmlJavaTypeAdapter@XmlAccessorType时,对该主题的快速搜索会导致当前open bug

此外,您应该在“协议”上使用@XmlRootElement。类而不是std::ios_base::failure,应保留给表示根XML元素的对象。