Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何避免使用JAXB和具有类似结构的类似容器的元素进行代码复制_Java_Xml_Jaxb - Fatal编程技术网

Java 如何避免使用JAXB和具有类似结构的类似容器的元素进行代码复制

Java 如何避免使用JAXB和具有类似结构的类似容器的元素进行代码复制,java,xml,jaxb,Java,Xml,Jaxb,形势 我使用MOXy的JAXB实现来处理一个大型XML文档,该文档的模式有许多相似的复杂类型。具体来说,大约有24种类型充当具有以下结构的列表包装器元素: <ITEMS attr1="X" attr2="Y"> <ITEM>...</ITEM> ... <EXTENSION/> <ITEMS> ... ... 对于这些类似于列表包装器的元素中的每一个,名称都会更改,所包含的列表元

形势

我使用MOXy的JAXB实现来处理一个大型XML文档,该文档的模式有许多相似的复杂类型。具体来说,大约有24种类型充当具有以下结构的列表包装器元素:

<ITEMS attr1="X" attr2="Y">
  <ITEM>...</ITEM>
  ...
  <EXTENSION/>
<ITEMS>

...
...
对于这些类似于列表包装器的元素中的每一个,名称都会更改,所包含的列表元素也会更改。但是,属性(都是可选的)和单个扩展元素(也是可选的)始终存在。以下是两种类型的使用示例:

<ROLES visible="false">
  <ROLE type="X"/>
  <ROLE type="Y"/>
</ROLES>

<PAYMENTS visible="true">
  <PAYMENT>
    <PAYEENAME>Joe</PAYEENAME>
  </PAYMENT>
  <EXTENSION>
    <SOMETHING>Here</SOMETHING>
  </EXTENSION>
</PAYMENTS>

乔
在这里
问题

我希望避免代码重复,因为这些元素之间唯一的变化是名称及其包含的一个或多个元素。最好的方法是什么

我只能看到两种可能的解决办法

1

使用泛型创建具体类,以指示要在发生更改的集合中使用的对象类型。然后使用MOXy的外部OX映射来指示该类的任何单独使用应该如何序列化。比如:

公共类GenericContainer{
@XmlAttribute
保护布尔可视性;
@xmlement(name=“扩展”)
受保护的扩展;
//在外部元文件中完成的OX映射
受保护的清单项目;
...
}
虽然我喜欢这个选项,但似乎不可能在每次使用的基础上重新定义类的OX映射

2

创建不带List属性的基类,然后为每个自定义包装器元素创建一个具体类。这个解决方案确实有效,但我最终会得到大约24个近似相同的类

要么是1可能,要么是有更好的方法来处理这个问题,我还没有想到

提前谢谢

公共类GenericContainer{
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;
}

}
私有布尔可见; 私有对象扩展; 私有列表节点; @XmlAttribute 公共布尔值可见(){ 返回可见; } 公共void集合可见(布尔可见){ 可见的;可见的; } @xmlement(name=“扩展”) 公共对象getExtension(){ 返回扩展; } 公共void集合扩展(对象扩展){ 这个扩展=扩展; } @XmlAnyElement 公共列表getNodes(){ 返回节点; } 公共void集合节点(列表节点){ this.nodes=节点; } }
和读取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;
    }
JAXBContext JAXBContext=JAXBContext.newInstance(“jaxbtest1”);
Unmarshaller um=jaxbContext.createUnmarshaller();
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
DocumentBuilder db=dbf.newDocumentBuilder();
documentdoc=db.parse(新文件(“src/test1.xml”);
Node=doc.getFirstChild();
JAXBElement jaxbE=um.unmarshal(节点,GenericContainer.class);
GenericContainer gc=jaxbE.getValue();
布尔vis=gc.isVisible();
元素ext=(元素)gc.getExtension();
对于(对象o:gc.getNodes()){
元素列表项=(元素)o;
}
但是代码复制真的很重要吗?如果您的模式具有列表容器类型的公共扩展基础,并且您正在使用xjc,那么为什么要避免使用不同的类呢?毕竟,JAXB背后的思想是为每个独特的复杂类型都有一个值类


如果您能够设计出处理类似但不同的XML类型的通用逻辑,并且不需要大量Java类,那么您可以切换到StAX。

这个示例并不真正符合我的要求,除非我遗漏了什么。它实际上不允许我将列表元素绑定到JAXB注释类,因为解组器会将所有内容都转换为org.w3c.dom.Element对象。换一种方式会少一点麻烦,但没有类型安全性。对于你关于代码复制的问题,你是对的,这并不十分重要。我真的很讨厌这样做。我最终选择了30多个几乎相同的课程,尽管我对此并不欣喜若狂。理想的情况是创建我自己的自定义java.util.Collection类,并提供泛型支持,但目前看来这是不可能的。