AbstractItem
別のクラスのフィールドとして使用されるという名前の抽象クラスがあるとします。XStreamを使用してXMLを生成する場合、要素タグをのインスタンスの具体的な実装に基づいて作成する必要がありますAbstractItem
。
私が得るもの:
<Test>
<item class="Item1" name="name 1" description="description 1"/>
</Test>
私が欲しいもの:
<Test>
<Item1 name="name 1" description="description 1"/>
</Test>
XStream
次のようにして、インスタンスにエイリアスを設定してみました。
stream.alias("Item1", Item1.class);
また、以下を使用します。
stream.aliasType("Item1", Item1.class);
上記のいずれも機能しませんでした。
わかりやすくするために、上記の実行可能な例を次に示します。
Test.java
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
@XStreamAlias("Test")
public class Test {
public AbstractItem item;
public static void main(String[] args){
Test t1 = new Test();
Item1 item1 = new Item1();
item1.name = "name 1";
item1.description = "description 1";
t1.item = item1;
XStream stream = new XStream();
stream.setMode(XStream.NO_REFERENCES);
stream.autodetectAnnotations(true);
stream.alias("Item1", Item1.class);
System.out.println(stream.toXML(t1));
}
}
AbstractItem.java
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
public abstract class AbstractItem {
@XStreamAsAttribute
public String name;
}
Item1.java
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
public class Item1 extends AbstractItem {
@XStreamAsAttribute
public String description;
}
更新: コンバータークラスを使用してこれを実行しようとしましたが、それでも正しくありません:
stream.registerConverter(
new Converter(){
@Override
public boolean canConvert(Class type) {
if (AbstractItem.class.isAssignableFrom(type)){
return true;
}
return false;
}
@Override
public void marshal(Object source, HierarchicalStreamWriter writer,
MarshallingContext context) {
AbstractItem item = (AbstractItem)source;
if(source instanceof Item1){
writer.startNode("Item1");
writer.addAttribute("description",((Item1)item).description);
} else if(source instanceof Item2){
writer.startNode("Item2");
writer.addAttribute("description", ((Item2)item).description);
} else {
writer.startNode("Item");
}
writer.addAttribute("name", item.name);
writer.endNode();
}
@Override
public Object unmarshal(HierarchicalStreamReader reader,
UnmarshallingContext context) {
// TODO Auto-generated method stub
AbstractItem item = null;
String nodeName = reader.getNodeName();
if (nodeName.equals("Item1")){
item = new Item1();
((Item1)item).description = reader.getAttribute("description");
} else if (nodeName.equals("Item2")){
item = new Item2();
((Item2)item).description = reader.getAttribute("description");
}
item.name = reader.getAttribute("name");
return item;
}
});
私が今得た結果は次のとおりです。
<Test>
<item class="Item1">
<Item1 description="description 1" name="name 1"/>
</item>
</Test>