简体   繁体   English

xstream使用Converter将复杂的XML反序列化为更简单的Java

[英]xstream unserialize complex XML to simpler java with Converter

I have surely a problem of understanding of Xstream converter. 我肯定有一个了解Xstream转换器的问题。

I have a pretty complex XML coming from legacy back office application and a just want to convert this one into a simpler java class or a Map with Converter. 我有一个非常复杂的XML,它来自旧版后台应用程序,并且只想将其转换为更简单的Java类或带有Converter的Map。

  1. I do not want to marshal to XML, just unmarshal 我不想编组到XML,只是取消编组
  2. I do not want to use annotation, just KISS 我不想使用注解,只想使用KISS

My XML is like 我的XML就像

<root>
    <agent>
        <id>123456789</id>
        <name>GABIN</name>
        <forname>Jean</forname>
        <unit>
            <legacyReference>AA</legacyReference>
            <name>SAN ANTONIO</name>
            <legacyName>SA</legacyName>
            <address>
                <number>1</number>
                <street>Sesam street</street>
                <city>NoWhere</city>
                <legacyID>AAZE-56</legacyID>
            </address>
            <legacyStructurBlablabla>
                <type>OFFICE</type>
                <data>
                    <foo>BAR</foo> 
                </data>
            </legacyStructurBlablabla>
            <...>
        </unit>
        <...> 
    </agent>
</root>

My destination class is very simple 我的目的地课很简单

class Agent {
    String id;
    String name;
    String forname;
    String unitName;
    String unitType;
    <...>

}

My main method looks like 我的主要方法看起来像

xStream = new XStream(new DomDriver());
stream = this.getClass().getClassLoader().getResourceAsStream("data/agent.xml") ;
xStream.alias("root", Map.class);
xStream.alias("agent", Agent.class);
xStream.registerConverter(new ResultConverter());
xStream.registerConverter(new AgentConverter());
xStream.ignoreUnknownElements();

Object obj = xStream.fromXML(stream);

I don't understand how to step down in favor of another converter. 我不知道该如何转而支持其他转换器。

public class ResultConverter implements Converter {

...


public Object unmarshal(HierarchicalStreamReader reader,
        UnmarshallingContext context) {
    Map<String, Object> agents = new HashMap<String, Object>();
    while( reader.hasMoreChildren() ) {
        reader.moveDown();
        // HOW I DO TO STEP DOWN IN FAVOR OF Agent CONVERTER ?
        reader.moveUp();
    }
    return agents;
}

I didn't see Xstream scrolled dow the thierarchy to activate my AgentConverter. 我没有看到Xstream滚动到层次结构来激活我的AgentConverter。

I surely missing the point 我肯定错过了重点

EDIT 编辑

Xstream may be not thr right tool for this. Xstream可能不是正确的工具。 I would use xmlbeam, according to Cfx advise. 根据Cfx的建议,我将使用xmlbeam。 XMLBeam projects the XML to a Java Class according to XPATH mapping. XMLBeam根据XPATH制图项目的XML到Java类。

Seems that you want the xml structure not to be reflected in your Java class. 似乎您希望xml结构不反映在Java类中。 If you stick to XStream, I have no solution. 如果您坚持使用XStream,我没有解决方案。 But there is an alternative framework that was made to solve exactly this issue. 但是,有一个替代框架可以解决此问题。 It uses annotations, but IMHO does not violate the KISS principle. 它使用注释,但是恕我直言不违反KISS原则。 Here is an example: 这是一个例子:

public interface Agent {

@XBRead("/root/agent/id")
String getId();

@XBRead("/root/agent/name")
String getName();

@XBRead("/root/agent/forename")
String getForname();

@XBRead("/root/agent/unit/name")
String getUnitName();

@XBRead("/root/agent/unit/legacyStructurBlablabla/type")
String getUnitType();

} }

You will define interfaces instead of classes, but the instances of these interfaces are useable just like POJOs. 您将定义接口而不是类,但是这些接口的实例就像POJO一样可用。 (with toString(), equals(), hashCode,...). (使用toString(),equals(),hashCode等)。 Creating instances of these interfaces is like this: 创建这些接口的实例是这样的:

Agent agent = new XBProjector().io().stream(stream).read(Agent.class);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM