如何在无中间容器类的情况下用JAXB映射多类型对象列表?
问题与解决方案
现有XML Schema
<xs:element name="document" type="Document"/> <xs:complexType name="Document"> <xs:sequence> <xs:element name="description" type="xs:string" minOccurs="0"/> <xs:element name="destination" type="xs:string" minOccurs="0"/> <xs:element name="tags" type="TagList" minOccurs="0"/> </xs:sequence> </xs:complexType> <xs:complexType name="TagList"> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:any processContents="lax" namespace="http://www.example.com/schema/tags"/> </xs:choice> </xs:complexType>
对应XML结构
<document> <description>the description</description> <destination>the destination</destination> <tags> <tagA> <propA1>...</propA1> <propA2>...</propA2> ... </tagA> <tagB> <propB1>...</propB1> <propB2>...</propB2> ... </tagB> ... </tags> </document>
其中tags节点包含0个或多个来自独立Schema定义的不同类型标签元素。
当前xjc生成的Java类
使用xjc工具生成的代码如下,需通过document.getTags().getAny()访问标签项:
public class Document { private String description; private String destination; private TagsList tags; // getter/setter } public class TagsList { private List<Object> any; // getter/setter }
需求
希望生成的Document类直接包含List<Object>类型的tags字段,如下所示:
public class Document { private String description; private String destination; private List<Object> tags; // getter/setter }
注:将TagList中的choice改为sequence无效果。
解决方案
方法1:内联复杂类型定义到Schema中
修改XML Schema,将TagList的复杂类型定义直接内联到Document的tags元素里,避免生成单独的TagList类:
<xs:element name="document" type="Document"/> <xs:complexType name="Document"> <xs:sequence> <xs:element name="description" type="xs:string" minOccurs="0"/> <xs:element name="destination" type="xs:string" minOccurs="0"/> <xs:element name="tags" minOccurs="0"> <xs:complexType> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:any processContents="lax" namespace="http://www.example.com/schema/tags"/> </xs:choice> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType>
重新运行xjc后,会直接在Document类中生成List<Object> tags字段,无需中间的TagList类。
方法2:使用JAXB自定义绑定文件
如果无法修改原始Schema,可以创建绑定文件(例如bindings.xjb),通过JAXB的绑定规则将TagList的内容内联到Document的tags属性:
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" version="2.1" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <jaxb:bindings schemaLocation="你的Schema文件路径.xsd"> <!-- 定位到Document类中的tags元素 --> <jaxb:bindings node="//xs:complexType[@name='Document']//xs:element[@name='tags']"> <jaxb:property> <!-- 内联复杂类型,直接生成List<Object>类型的属性 --> <jaxb:inline/> </jaxb:property> </jaxb:bindings> </jaxb:bindings> </jaxb:bindings>
运行xjc时指定该绑定文件:
xjc -b bindings.xjb 你的Schema文件路径.xsd
两种方法都能生成符合需求的Document类,直接通过document.getTags()获取标签列表。
内容的提问来源于stack exchange,提问作者Gaetan
相关产品推荐
相关产品推荐

