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

我有一个问题是让Moxy为继承对象列表生成“好”的 XMLJSON. 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);
    }
}

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

zoo = new Zoo();
    zoo.addAnimal(new Tiger("Hobbes"));
    zoo.addAnimal(new Lion("Simba"));
    zoo.addAnimal(new Tiger("Sherikan"));

看起来像:

<?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"
        } ]
     }
  }

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

如果我将Zoo.animals上的注释更改为@XmlElement,则JSON输出看起来很好,但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>

我想出解决这个问题的唯一方法是创建一个外部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>

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

解决方法

注意:我是 EclipseLink JAXB (MOXy)领导者,也是 JAXB (JSR-222)专家组的成员

The way that the Moxy uses the type as key does not preserve order
among the elements in the list. Is this a bug or feature?

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

The only way I’ve come up with to solve this is to create an external
OXM binding file to override the annotation on Zoo.animals. The
binding below is registered using the property of
JAXBContextProperties.OXM_MetaDATA_SOURCE.

这就是我建议解决你的用例的方法.

相关文章

php输出xml格式字符串
J2ME Mobile 3D入门教程系列文章之一
XML轻松学习手册
XML入门的常见问题(一)
XML入门的常见问题(三)
XML轻松学习手册(2)XML概念