当前位置: 首页 > 知识库问答 >
问题:

如何用XStream将同名节点反序列化为两个不同的类

乌翔
2023-03-14

反序列化XML文件时遇到问题。

<mission>
    <branch>
        <alternative uid="0" type="ALT_MONITOR"/>
        <alternative uid="1" type="ALT_IF" condition="i==10"/>
    </branch>
</mission>
public abtract class Alternative {
    @XStreamAsAttribute
    public int uid;
    @XStreamAsAttribute
    public String type;
}
@XStreamAlias("alternative")
public class AlternativeA extends Alternative {
}

@XStreamAlias("alternative")
public class AlternativeB extends Alternative {
    @XStreamAsAttribute
    public String condition;
}
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);
    }
}

无法将类型AlternativeB转换为类型AlternativeA

你们中有没有人对什么可能导致错误有一个想法或一个int?提前谢谢你。

共有1个答案

红鸿运
2023-03-14

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>
 类似资料:
  • 我正在努力用本地化反序列化世界天气在线API结果。 是否有更好、更简单的解决方案,只为lang对象编写一个自定义反序列化器,并允许GSON自动反序列化其余数据?

  • 我之前的问题没有得到任何结果,可能是我问得不对,或者太详细了。 现在我的基本问题是,如何将一个具有一个类名的JSON对象反序列化为一个具有不同类名的Java对象? 例如,服务器发送/期望的JSON类是“18”(我对此控制为零)。我的Java班不可能是“18”,所以是“_18”。 简单地执行new Gson().fromjson()没有任何帮助,即使使用了不同的命名策略;_18对象始终为NULL。从

  • 我在尝试“反序列化”对象时遇到以下错误: 我需要能够使用这个XStream库序列化/反序列化对象,甚至是那些没有参数构造函数的对象。

  • 我正在使用xstream并尝试将列表序列化为XML。我需要一个输出结构 序列化的对象类似于 我的问题与作为对象集合的XStream-Root类似,但我希望在不使用包装对象的情况下这样做。

  • 这是保存过程开始的地方。我定义了一个抽象方法,以后在运行时已知的类中实现。 这里我知道的类型,我想调用一个方法。 所以问题是ConfigurationPersistenceHelper中的方法。运行此方法时,配置中得到的不是而是。 我知道我可以在每个具体应用程序类的方法中实现反序列化器逻辑。但这会导致大量重复代码。这是我目前的解决方案。 此外,我知道我可以将类型从(其中类型在运行时仍然可用)传递给