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

时间:2013-12-13 15:18:21

标签: xml json inheritance 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);
    }
}

从以下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>

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

1 个答案:

答案 0 :(得分:2)

注意:我是EclipseLink JAXB (MOXy)主管,是JAXB (JSR-222)专家组的成员

  

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

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

  

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

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