如何将同名节点反序列化为两个不同的 类 和 XStream
How to deserialize same name node into two different classes with XStream
我在反序列化 XML 文件时遇到问题。
我的文件是这样的:
<mission>
<branch>
<alternative uid="0" type="ALT_MONITOR"/>
<alternative uid="1" type="ALT_IF" condition="i==10"/>
</branch>
</mission>
我有一个 class 叫做 Alternative:
public abtract class Alternative {
@XStreamAsAttribute
public int uid;
@XStreamAsAttribute
public String type;
}
此 class 由另外两个 class 扩展:
@XStreamAlias("alternative")
public class AlternativeA extends Alternative {
}
@XStreamAlias("alternative")
public class AlternativeB extends Alternative {
@XStreamAsAttribute
public String condition;
}
然后我有一个 xStream 转换器 :
public class AlternativeConverter extends ReflectionConverter {
public AlternativesConverter(Mapper mapper, ReflectionProvider reflectionProvider) {
super(mapper, reflectionProvider);
}
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
if (reader.getAttribute("condition") != null) {
AlternativeA alternativeA = new AlternativeA();
alternativeA.setUid(Integer.parseInt(reader.getAttribute("uid")));
alternativeA.setCondition(reader.getAttribute("condition"));
return super.doUnmarshal(alternativeA, reader, context);
}else {
AlternativeB alternativeB = new AlternativeB();
alternativeB.setUid(Integer.parseInt(reader.getAttribute("uid")));
return super.doUnmarshal(alternativeB, reader, context);
}
}
@SuppressWarnings("unchecked")
@Override
public boolean canConvert(Class clazz) {
return Alternative.class.isAssignableFrom(clazz);
}
}
但是当我尝试将 xml 转换为对象时。当它到达有条件的备选方案时,它会抛出异常:
Cannot convert type AlternativeB to type AlternativeA
你们中的任何人对可能导致该错误的原因有任何想法或见解吗?
提前谢谢你。
Java:
package de.mosst.spielwiese;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.converters.reflection.ReflectionConverter;
import com.thoughtworks.xstream.converters.reflection.ReflectionProvider;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.mapper.Mapper;
import lombok.Data;
public class XStreamMultiClassesTest {
@Test
public void smokeTest() {
InputStream file = XStreamMultiClassesTest.class.getResourceAsStream("XStreamMultiClassesTest.xml");
XStream xStream = new XStream();
xStream.ignoreUnknownElements();
xStream.processAnnotations(Mission.class);
xStream.processAnnotations(Alternative.class);
Converter converter = new AlternativeConverter(xStream.getMapper(), xStream.getReflectionProvider());
xStream.registerConverter(converter);
Mission mission = (Mission) xStream.fromXML(file);
System.out.println(mission);
mission.branch.forEach(a -> {
System.out.println(a.getClass());
if (a instanceof AlternativeA) {
System.out.println("- condition: " + ((AlternativeA) a).condition);
}
});
}
public class AlternativeConverter extends ReflectionConverter {
public AlternativeConverter(Mapper mapper, ReflectionProvider reflectionProvider) {
super(mapper, reflectionProvider);
}
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
Alternative alternative = null;
if (reader.getAttribute("condition") != null) {
alternative = new AlternativeA();
((AlternativeA) alternative).condition = reader.getAttribute("condition");
} else {
alternative = new AlternativeB();
}
alternative.uid = Integer.parseInt(reader.getAttribute("uid"));
return super.doUnmarshal(alternative, reader, context);
}
@Override
public boolean canConvert(@SuppressWarnings("rawtypes") Class clazz) {
return Alternative.class.isAssignableFrom(clazz);
}
}
@XStreamAlias("mission")
@Data
class Mission {
public List<Alternative> branch = new ArrayList<>();
}
@XStreamAlias("alternative")
@Data
abstract class Alternative {
@XStreamAsAttribute
public int uid;
@XStreamAsAttribute
public String type;
}
class AlternativeA extends Alternative {
public String condition;
}
class AlternativeB extends Alternative {
}
}
XML:
<?xml version="1.0" encoding="UTF-8"?>
<mission>
<branch>
<alternative uid="0" type="ALT_MONITOR" />
<alternative uid="1" type="ALT_IF" condition="i==10" />
</branch>
</mission>
我在反序列化 XML 文件时遇到问题。
我的文件是这样的:
<mission>
<branch>
<alternative uid="0" type="ALT_MONITOR"/>
<alternative uid="1" type="ALT_IF" condition="i==10"/>
</branch>
</mission>
我有一个 class 叫做 Alternative:
public abtract class Alternative {
@XStreamAsAttribute
public int uid;
@XStreamAsAttribute
public String type;
}
此 class 由另外两个 class 扩展:
@XStreamAlias("alternative")
public class AlternativeA extends Alternative {
}
@XStreamAlias("alternative")
public class AlternativeB extends Alternative {
@XStreamAsAttribute
public String condition;
}
然后我有一个 xStream 转换器 :
public class AlternativeConverter extends ReflectionConverter {
public AlternativesConverter(Mapper mapper, ReflectionProvider reflectionProvider) {
super(mapper, reflectionProvider);
}
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
if (reader.getAttribute("condition") != null) {
AlternativeA alternativeA = new AlternativeA();
alternativeA.setUid(Integer.parseInt(reader.getAttribute("uid")));
alternativeA.setCondition(reader.getAttribute("condition"));
return super.doUnmarshal(alternativeA, reader, context);
}else {
AlternativeB alternativeB = new AlternativeB();
alternativeB.setUid(Integer.parseInt(reader.getAttribute("uid")));
return super.doUnmarshal(alternativeB, reader, context);
}
}
@SuppressWarnings("unchecked")
@Override
public boolean canConvert(Class clazz) {
return Alternative.class.isAssignableFrom(clazz);
}
}
但是当我尝试将 xml 转换为对象时。当它到达有条件的备选方案时,它会抛出异常:
Cannot convert type AlternativeB to type AlternativeA
你们中的任何人对可能导致该错误的原因有任何想法或见解吗? 提前谢谢你。
Java:
package de.mosst.spielwiese;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.converters.reflection.ReflectionConverter;
import com.thoughtworks.xstream.converters.reflection.ReflectionProvider;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.mapper.Mapper;
import lombok.Data;
public class XStreamMultiClassesTest {
@Test
public void smokeTest() {
InputStream file = XStreamMultiClassesTest.class.getResourceAsStream("XStreamMultiClassesTest.xml");
XStream xStream = new XStream();
xStream.ignoreUnknownElements();
xStream.processAnnotations(Mission.class);
xStream.processAnnotations(Alternative.class);
Converter converter = new AlternativeConverter(xStream.getMapper(), xStream.getReflectionProvider());
xStream.registerConverter(converter);
Mission mission = (Mission) xStream.fromXML(file);
System.out.println(mission);
mission.branch.forEach(a -> {
System.out.println(a.getClass());
if (a instanceof AlternativeA) {
System.out.println("- condition: " + ((AlternativeA) a).condition);
}
});
}
public class AlternativeConverter extends ReflectionConverter {
public AlternativeConverter(Mapper mapper, ReflectionProvider reflectionProvider) {
super(mapper, reflectionProvider);
}
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
Alternative alternative = null;
if (reader.getAttribute("condition") != null) {
alternative = new AlternativeA();
((AlternativeA) alternative).condition = reader.getAttribute("condition");
} else {
alternative = new AlternativeB();
}
alternative.uid = Integer.parseInt(reader.getAttribute("uid"));
return super.doUnmarshal(alternative, reader, context);
}
@Override
public boolean canConvert(@SuppressWarnings("rawtypes") Class clazz) {
return Alternative.class.isAssignableFrom(clazz);
}
}
@XStreamAlias("mission")
@Data
class Mission {
public List<Alternative> branch = new ArrayList<>();
}
@XStreamAlias("alternative")
@Data
abstract class Alternative {
@XStreamAsAttribute
public int uid;
@XStreamAsAttribute
public String type;
}
class AlternativeA extends Alternative {
public String condition;
}
class AlternativeB extends Alternative {
}
}
XML:
<?xml version="1.0" encoding="UTF-8"?>
<mission>
<branch>
<alternative uid="0" type="ALT_MONITOR" />
<alternative uid="1" type="ALT_IF" condition="i==10" />
</branch>
</mission>