情况
我正在使用MOXy的JAXB实现来处理大型XML文档,其架构有许多类似的复杂类型.具体来说,有大约24种类型作为列表包装元素,具有以下结构:
<ITEMS attr1="X" attr2="Y">
<ITEM>...</ITEM>
...
<EXTENSION/>
<ITEMS>
Run Code Online (Sandbox Code Playgroud)
对于这些类似于list-wrapper的元素中的每一个,名称都会更改,并且包含的列表元素会发生更改.但是,始终存在属性(都是可选的)和单个EXTENSION元素(也是可选的).以下是两种类型的使用示例:
<ROLES visible="false">
<ROLE type="X"/>
<ROLE type="Y"/>
</ROLES>
<PAYMENTS visible="true">
<PAYMENT>
<PAYEENAME>Joe</PAYEENAME>
</PAYMENT>
<EXTENSION>
<SOMETHING>Here</SOMETHING>
</EXTENSION>
</PAYMENTS>
Run Code Online (Sandbox Code Playgroud)
问题
我想避免代码重复,因为这些元素之间唯一的变化是名称和它包含的一个或多个元素.做这个的最好方式是什么?
我只能看到两种可能的解决方案.
1
使用泛型创建具体类,以指示要在更改的集合中使用的对象类型.然后使用MOXy的外部OX映射来指示如何对类的任何个人使用进行序列化.就像是:
public class GenericContainer<T> {
@XmlAttribute
protected Boolean visibile;
@XmlElement(name = "Extension")
protected Extension extension;
// OX Mappings done in external meta file
protected List<T> items;
...
}
Run Code Online (Sandbox Code Playgroud)
虽然我喜欢这个选项,但似乎不可能在每次使用的基础上重新定义类的OX映射.
2
创建不带List属性的基类,然后为每个自定义包装元素创建一个具体类.这个解决方案肯定有效,但我最终会得到大约二十几个近乎相同的类.
是#1可能还是有更好的方法来处理这个我没有想到的?
提前致谢!
public class GenericContainer {
private Boolean visible;
private Object extension;
private List<Object> nodes;
@XmlAttribute
public Boolean isVisible() {
return visible;
}
public void setVisible(Boolean visible) {
this.visible = visible;
}
@XmlElement(name="EXTENSION")
public Object getExtension() {
return extension;
}
public void setExtension(Object extension) {
this.extension = extension;
}
@XmlAnyElement
public List<Object> getNodes() {
return nodes;
}
public void setNodes(List<Object> nodes) {
this.nodes = nodes;
}
}
Run Code Online (Sandbox Code Playgroud)
并读取 XML 实例
JAXBContext jaxbContext = JAXBContext.newInstance("jaxbtest1");
Unmarshaller um = jaxbContext.createUnmarshaller();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new File("src/test1.xml"));
Node node = doc.getFirstChild();
JAXBElement<GenericContainer> jaxbE = um.unmarshal(node, GenericContainer.class);
GenericContainer gc = jaxbE.getValue();
Boolean vis = gc.isVisible();
Element ext = (Element)gc.getExtension();
for(Object o : gc.getNodes()) {
Element listItem = (Element)o;
}
Run Code Online (Sandbox Code Playgroud)
但代码重复真的很重要吗?如果您的架构具有列表容器类型的公共扩展基础并且您正在使用 xjc,为什么要避免不同的类?毕竟,JAXB 背后的想法是为每个唯一的复杂类型提供一个值类。
如果您可以制作通用逻辑来处理相似但不同的 XML 类型,并且不需要大量 Java 类,您可以切换到 StAX。
归档时间: |
|
查看次数: |
694 次 |
最近记录: |