Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.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,目前,我的项目中有以下环境: public abstract class Foo { private List<Thing> things; public List<Thing> getThings() { return this.things; } } public abstract class Bar extends Foo { @XmlElements({@XmlElement(name = "first", type = First.c

目前,我的项目中有以下环境:

public abstract class Foo {

   private List<Thing> things;

   public List<Thing> getThings() { return this.things; }
}

public abstract class Bar extends Foo {


   @XmlElements({@XmlElement(name = "first", type = First.class)})
   public List<Thing> getThings() { return super.getThings(); }

}

public class Bobar extends Bar {

   @XmlElements({@XmlElement(name = "second", type = Second.class)})
   public List<Thing> getThings() { return super.getThings(); }

}
条形码对象在集合中只有一个元素,而不是两个。当我尝试执行
object.getThings()
时,
First
元素完全丢失,它的大小是1,集合中唯一的对象是
Second
的实例。有人能帮助我如何在集合中获得这两个对象吗?如果这是不可能的,我怎样才能实现类似的目标

我这样做的原因是(在我的项目逻辑中)每个
Bobar
s things集合在其集合中都有一个
First
,但不是每个
Bar
在其集合中都有一个
Second
,并且
Foo
是一个泛型类

编辑: 当我更改XML文档中的顺序时,输出是不同的

<bobar>
   <second>blablabla</second>
   <first>blublublu</first>
</bobar>
如果我这样做

<bobar>
   <third>bliblibli</third>
   <second>blablabla</second>
   <first>blublublu</first>
</bobar>

blibili
喋喋不休
布鲁

理论上,我认为这不应该根据它生成的XML模式进行验证,因为这里的顺序不正确。但除此之外,在这种情况下,我得到了
第二个
第一个
,第三个丢失了。

下面是如何利用
@xmltransive
映射这个用例的:

package forum11698160;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class First extends Thing {

}
package forum11698160;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Second extends Thing {

}
Bobar

您无法在子类中扩展映射,因此需要确保在执行
@xmlmelements
映射时,您可以完成所有操作(请参阅:)

演示

package forum11698160;

import java.util.*;

public abstract class Foo {

    private List<Thing> things = new ArrayList<Thing>();

    public List<Thing> getThings() {
        return this.things;
    }

}
package forum11698160;

import java.util.*;

public abstract class Foo {

    private List<Thing> things = new ArrayList<Thing>();

    public List<Thing> getThings() {
        return this.things;
    }

}
以下演示代码可用于演示一切工作正常:

package forum11698160;

import java.io.File;
import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Bobar.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum11698160/input.xml");
        Bobar bobar =  (Bobar) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(bobar, System.out);
    }

}
package forum11698160;

import java.io.File;
import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Bobar.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum11698160/input.xml");
        Bobar bobar =  (Bobar) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(bobar, System.out);
    }

}
input.xml/Output

<?xml version="1.0" encoding="UTF-8"?>
<bobar>
   <first/>
   <second/>
</bobar>
package forum11698160;

public class First implements Thing {

}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<bobar>
    <first/>
    <second/>
</bobar>
首先

<?xml version="1.0" encoding="UTF-8"?>
<bobar>
   <first/>
   <second/>
</bobar>
package forum11698160;

public class First implements Thing {

}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<bobar>
    <first/>
    <second/>
</bobar>

package forum11698160;

public class Second implements Thing {

}

不可能对超级类型上的属性进行注释,也不可能以增量方式将子类型添加到该映射中。下面是一种支持您所关注的所有用例的方法。需要注意的一点是,对象层次结构中的所有级别都支持相同的元素集。您需要使用外部验证手段来限制所需的值

如果
Thing
是一个类而不是一个接口,并且
第一个
第二个
扩展
Thing
,那么您可能有兴趣使用
@xmlementref
而不是
@xmlements
(请参阅:)。它将为您提供更大的灵活性,但需要进行一些验证(很难限制有效值集)

我们将用
@xmltransive
注释
,以便JAXB实现不会处理它

package forum11698160;

import java.util.List;

import javax.xml.bind.annotation.XmlTransient;

@XmlTransient
public abstract class Bar extends Foo {

    public List<Thing> getThings() {
        return super.getThings();
    }

}
东西

package forum11698160;

public interface Thing {

}
由于JAXB实现不能使用反射来查找类型的所有子类,因此我们可以使用
@xmlseea
注释来提供帮助。如果不使用此注释,则在引导
JAXBContext
时需要包含所有子类型

package forum11698160;

import javax.xml.bind.annotation.XmlSeeAlso;

@XmlSeeAlso({First.class, Second.class})
public class Thing {

}
首先

<?xml version="1.0" encoding="UTF-8"?>
<bobar>
   <first/>
   <second/>
</bobar>
package forum11698160;

public class First implements Thing {

}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<bobar>
    <first/>
    <second/>
</bobar>
我们需要首先用
@XmlRootElement
注释

package forum11698160;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class First extends Thing {

}
package forum11698160;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Second extends Thing {

}

package forum11698160;

public class Second implements Thing {

}
Second
还需要用
@XmlRootElement
注释:

package forum11698160;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class First extends Thing {

}
package forum11698160;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Second extends Thing {

}
演示

package forum11698160;

import java.util.*;

public abstract class Foo {

    private List<Thing> things = new ArrayList<Thing>();

    public List<Thing> getThings() {
        return this.things;
    }

}
package forum11698160;

import java.util.*;

public abstract class Foo {

    private List<Thing> things = new ArrayList<Thing>();

    public List<Thing> getThings() {
        return this.things;
    }

}
input.xml/Output

<?xml version="1.0" encoding="UTF-8"?>
<bobar>
   <first/>
   <second/>
</bobar>
package forum11698160;

public class First implements Thing {

}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<bobar>
    <first/>
    <second/>
</bobar>


其他文件

以下是运行此示例所需的其他文件:

Foo

package forum11698160;

import java.util.*;

public abstract class Foo {

    private List<Thing> things = new ArrayList<Thing>();

    public List<Thing> getThings() {
        return this.things;
    }

}
package forum11698160;

import java.util.*;

public abstract class Foo {

    private List<Thing> things = new ArrayList<Thing>();

    public List<Thing> getThings() {
        return this.things;
    }

}
UM11698160的
包;
导入java.util.*;
公共抽象类Foo{
private List things=new ArrayList();
公共列表getThings(){
归还这个东西;
}
}

我知道并且正在使用这种方法,但是如果我想扩展
Bobar
,并在可能的事情列表中添加一个新元素,有什么方法可以做到吗?@SHiRKiT-我已经添加了第二个答案()。它使用
@xmlementref
,这将以较少的验证为代价为您提供更大的灵活性。@blaise doughan是否可以从xsd和必要的绑定文件生成上述映射?或者可以手动完成吗?嗯,我发现我不能做我想做的事。我只是不明白为什么它不能按预期的方式工作。我想做的是在清单上增加更多的可能性。我不明白为什么如果我对
Bobar
进行扩展,让我们称之为
Fobar
,并用
@xmlmelements
注释
getThings
,列表不会同时包含
Bobar
Fobar
中的元素,因为在XML模式中,所有这些属性都会显示出来,因为它是一个扩展。模式生成正确,问题是当JAXB解组时,就会发生这种情况。我很难过,真的很难过=\在XML模式中,我将
Fobar
作为complexType,使用complexContent和
Bobar
作为扩展基础
Fobar
将在序列中包含元素
第三个
,而
Bobar
包含元素
第一个
第二个
。我认为JAXB为
Bobar
实例化了一个列表并将元素放入其中,然后为
Fobar
实例化了另一个列表并放入元素,但是如果更改元素的顺序,就会发生一些奇怪的事情。我想那时候我只能忍受了。谢谢你的回答和时间!