Moxy:对象列表XML和JSON不能同时看起来很好

use*_*799 5 xml inheritance json jaxb moxy

我有一个问题是让Moxy为继承对象列表生成"好"的XML和JSON.XML查找或JSON看起来都很好,但不是同时.这是模型:

public static abstract class Animal {
    private String name;

    protected Animal() {
    }
    protected Animal(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
@XmlRootElement
public static class Tiger extends Animal {
    public Tiger() {
    }
    public Tiger(String name) {
        super(name);
    }
}

@XmlRootElement
public static class Lion extends Animal {
    public Lion() {
    }
    public Lion(String name) {
        super(name);
    }
}

@XmlRootElement
public static class Zoo {
    private List<Animal> animals = new ArrayList<>();

    @XmlElementRef
    public List<Animal> getAnimals() {
        return animals;
    }
    public void setAnimals(List<Animal> animals) {
        this.animals = animals;
    }
    public void addAnimal(Animal a) {
        animals.add(a);
    }
}
Run Code Online (Sandbox Code Playgroud)

从以下Zoo实例生成的XML和JSON

    zoo = new Zoo();
    zoo.addAnimal(new Tiger("Hobbes"));
    zoo.addAnimal(new Lion("Simba"));
    zoo.addAnimal(new Tiger("Sherikan"));
Run Code Online (Sandbox Code Playgroud)

看起来像:

  <?xml version="1.0" encoding="UTF-8"?>
  <zoo>
     <tiger>
        <name>Hobbes</name>
     </tiger>
     <lion>
        <name>Simba</name>
     </lion>
     <tiger>
        <name>Sherikan</name>
     </tiger>
  </zoo>
  {
     "zoo" : {
        "tiger" : [ {
           "name" : "Hobbes"
        }, {
           "name" : "Sherikan"
        } ],
        "lion" : [ {
           "name" : "Simba"
        } ]
     }
  }
Run Code Online (Sandbox Code Playgroud)

XML看起来也是我想要的,但JSON很奇怪.Moxy使用类型作为键的方式不会保留列表中元素之间的顺序.这是一个错误或功能吗?

如果我改变了注释Zoo.animals,以@XmlElementJSON的输出看起来不错,但XML输出已改变的东西,我不能使用.

  {
     "zoo" : {
        "animals" : [ {
           "type" : "tiger",
           "name" : "Hobbes"
        }, {
           "type" : "lion",
           "name" : "Simba"
        }, {
           "type" : "tiger",
           "name" : "Sherikan"
        } ]
     }
  }
  <?xml version="1.0" encoding="UTF-8"?>
  <zoo>
     <animals xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="tiger">
        <name>Hobbes</name>
     </animals>
     <animals xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="lion">
        <name>Simba</name>
     </animals>
     <animals xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="tiger">
        <name>Sherikan</name>
     </animals>
  </zoo>
Run Code Online (Sandbox Code Playgroud)

我想出解决这个问题的唯一方法是创建一个外部OXM绑定文件来覆盖注释Zoo.animals.下面的绑定是使用JAXBContextProperties.OXM_METADATA_SOURCE的属性注册的.

  <?xml version="1.0"?>
  <xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xml-accessor-type="PUBLIC_MEMBER" xml-accessor-order="ALPHABETICAL"
                xml-mapping-metadata-complete="false"
                package-name="com.example">
     <java-types>
        <java-type name="com.example.JAXBTest2$Zoo">
           <java-attributes>
              <xml-element java-attribute="animals"/>
           </java-attributes>
        </java-type>
     </java-types>
  </xml-bindings>
Run Code Online (Sandbox Code Playgroud)

有没有更好的解决方案,不使用外部绑定文件?

bdo*_*han 2

注意: 我是EclipseLink JAXB (MOXy)负责人,也是JAXB (JSR-222)专家组的成员

Moxy 使用类型作为键的方式不保留列表中元素之间的顺序。这是错误还是功能?

我们故意这样做是为了防止密钥重复。

我想出解决这个问题的唯一方法是创建一个外部 OXM 绑定文件来覆盖 Zoo.animals 上的注释。下面的绑定是使用 JAXBContextProperties.OXM_METADATA_SOURCE 的属性注册的。

这就是我建议解决您的用例的方式。