我想序列化一个对象层次结构,包括一个从基类'Thing'派生的对象列表。这很好用,包括反序列化 - 但XML-Simple坚持编写一个指定实际使用的Java类的属性
当我使用下面的java代码创建一个xml文件时,内容如下:
<example1>
<things>
<fruit class="com.mumpitz.simplexmltest.Apple" id="17">
<sugar>212</sugar>
</fruit>
<fruit class="com.mumpitz.simplexmltest.Orange" id="25" weight="11.2"/>
</things>
</example1>
但这不是我想要的。 我想要
<example1>
<things>
<apple id="17">
<sugar>212</sugar>
</apple>
<orange id="25" weight="11.2"/>
</things>
</example1>
'apple'和'orange'元素没有class属性,而不是'fruit'具有这样的属性。这可能吗?
(第二个xml符合现有架构;添加额外属性不是一个选项)
以下是代码:
package com.mumpitz.simplexmltest;
import java.io.File;
import java.util.ArrayList;
import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.Element;
import org.simpleframework.xml.ElementList;
import org.simpleframework.xml.Root;
import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;
class Fruit {
@Attribute(name = "id")
protected final int id;
Fruit(
@Attribute(name = "id")
int id) {
this.id = id;
}
int getObjectId() {
return id;
}
}
@Root
class Apple extends Fruit {
private final int sugar;
@Element(type = Fruit.class)
public Apple(
@Attribute(name = "id")
int id,
@Element(name = "sugar")
int sugar) {
super(id);
this.sugar = sugar;
}
@Element(name = "sugar")
public int getSugar() {
return this.sugar;
}
@Override
public String toString() {
return "id: " + id + ", sugar: " + sugar;
}
}
@Root
class Orange extends Fruit {
@Attribute
public double weight;
public Orange(
@Attribute(name = "id")
int id) {
super(id);
}
@Override
public String toString() {
return "id: " + id + ", weight: " + weight;
}
}
@Root
public class Example1 {
@ElementList
public ArrayList<Fruit> things = new ArrayList<Fruit>();
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("things:\n");
for (int i=0; i<things.size(); i++) {
sb.append(" " + things.get(i).toString() + "\n");
}
return sb.toString();
}
//////////////////////////////////
static Example1 createDummy() {
Example1 d = new Example1();
d.things.add(new Apple(17, 212));
Orange or = new Orange(25);
or.weight = 11.2;
d.things.add(or);
return d;
}
static String msg;
static Example1 res;
static public String getMessage() {
String m = msg;
msg = null;
return m;
}
static public boolean write(String path) {
Serializer serializer = new Persister();
Example1 example = Example1.createDummy();
File result = new File(path);
try {
serializer.write(example, result);
} catch (Exception e) {
e.printStackTrace();
msg = e.getMessage();
return false;
}
return true;
}
static public boolean read(String path) {
Serializer serializer = new Persister();
File source = new File(path);
try {
res = serializer.read(Example1.class, source);
} catch (Exception e) {
e.printStackTrace();
msg = e.getMessage();
return false;
}
return true;
}
public static Object getResult() {
return res;
}
}
答案 0 :(得分:4)
使用@ElementListUnion注释
package com.mumpitz.simplexmltest;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.Element;
import org.simpleframework.xml.ElementList;
import org.simpleframework.xml.ElementListUnion;
import org.simpleframework.xml.Root;
import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;
// the base class
@Element
class Thing {
static int count=0;
Thing() {
this.id = ++count;
}
@Attribute
protected int id;
public int getId() {
return id;
}
}
// first derived class
@Element
class Car extends Thing {
@Attribute
private String name;
Car(@Attribute(name="name") String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "ID: " + id + " Car: " + name;
}
}
// second derived class
@Element
class House extends Thing {
@Attribute
private int price;
House(@Attribute(name="price") int price) {
this.price = price;
}
public int getPrice() {
return this.price;
}
@Override
public String toString() {
return "ID: " + id + " House: " + price;
}
}
// a class with a list of base class instances
@Root(name="ListOfThings")
public class Example4 {
// specify the derived classes used in the list
@ElementListUnion({
@ElementList(entry="house", inline=true, type=House.class),
@ElementList(entry="car", inline=true, type=Car.class)
})
private ArrayList<Thing> list = new ArrayList<Thing>();
public void add(Thing t) {
list.add(t);
}
public List<Thing> getProperties() {
return list;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Example4 contains " + list.size() + " elements:\n");
for (Thing t : list) {
sb.append(" " + t.toString() + "\n");
}
return sb.toString();
}
//////////////////////////////////
// test code
//////////////////////////////////
static String msg;
static Example4 res;
static public String getMessage() {
String m = msg;
msg = null;
return m;
}
static private Example4 createDummy() {
Example4 d = new Example4();
d.add(new Car("Mercedes"));
d.add(new House(34000000));
d.add(new Car("VW"));
d.add(new House(230000));
return d;
}
//////////////////////////////////
// serialize / deserialize
//////////////////////////////////
static public boolean write(String path) {
Serializer serializer = new Persister();
File result = new File(path);
Example4 example = Example4.createDummy();
try {
serializer.write(example, result);
} catch (Exception e) {
e.printStackTrace();
msg = e.getMessage();
return false;
}
return true;
}
static public boolean read(String path) {
Serializer serializer = new Persister();
File source = new File(path);
try {
res = serializer.read(Example4.class, source);
} catch (Exception e) {
e.printStackTrace();
msg = e.getMessage();
return false;
}
return true;
}
public static Object getResult() {
return res;
}
}