Jaxb:如何在解组时替换给定对象树中的类/绑定 [英] Jaxb: How to replace a class/binding in given object tree while unmarshalling

查看:21
本文介绍了Jaxb:如何在解组时替换给定对象树中的类/绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一组给定的类来将 xml 解组为对象树.现在我得到了一个扩展的 xml,想用扩展版本替换对象树中的一个类.

I have a given set of classes to unmarshall a xml into an object tree. Now I get a extended xml and want to replace one class in the object tree with an extended version.

XML 文件

<?xml version="1.0" encoding="UTF-8"?>
<RootNode_001>
    <systemId>on the 4</systemId>
    <systemName>give me some more</systemName>
    <person>
        <firstname>James</firstname>
        <lastname>Brown</lastname>
        <address>
            <street>Funky</street>
            <city>Town</city>
            <type>HOME</type> <!-- this is the new field -->
        </address>
    </person>
</RootNode_001>

我使用新字段创建一个新的地址类,如下所示:

I create a new address class with the new field like this:

public class ExtAddress extends Address {
    // inherit from address and add new field
    private String type;

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }
}

现在我尝试解组成一个对象树,我希望 ExtAddress 像这样成为树的一部分:

Now I try to unmarshall into an object tree and I expect ExtAddress to be part of the tree like this:

public class Runner {

    public static void main ( String argv[] ) throws Exception {
        File file = new File( "basic.xml" );
        Class cls = RootNode.class;

        // create a context with the root node and the replacement class
        JAXBContext jaxbContext = JAXBContext.newInstance( ExtAddress.class, cls );
        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
        JAXBElement jaxbElement = unmarshaller.unmarshal( new StreamSource( file ), cls );
        RootNode rootNode = (RootNode) jaxbElement.getValue();

        System.out.println( rootNode.getClass().getName() );
        System.out.println( rootNode.getPerson().getClass().getName()  );
        // this returns Address but I want ExtAddress
        System.out.println( rootNode.getPerson().getAddress().getClass().getName()  );
    }
}

到目前为止我没有使用注释.解组后的对象树返回 Address 而不是 ExtAddress.如果我添加一个 XmlType 注释,我会得到一个异常:

I use no annotations so far. The unmarshalled object tree return Address and not ExtAddress. If I add a XmlType annotation I get an exception:

@XmlTyp( name = "address" )
ExtAddress extends Address {
  ...
}

Exception in thread "main" com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
Two classes have the same XML type name "address". Use @XmlType.name and @XmlType.namespace to assign different names to them.
    this problem is related to the following location:
        at jaxb.standard.Address
        at jaxb.ExtAddress

我尝试了很多方法,但这似乎非常接近解决方案.我如何告诉 jaxb 使用继承的类而不是原始类.

I tried many things but this seems to be very near to a solution. How can I tell jaxb to use an inherited class instead of the original one.

我想在库中创建一组标准类,并且能够稍后在 xml 中出现新字段时更改对象树作为扩展.

I want to delvier a set of standard classes in a library and be able to change the object tree later as an extension when new fields in xml appear.

推荐答案

这里讨论了一个类似的话题:JAXB 继承,解组到编组类的子类

A similar topic is discussed here: JAXB inheritance, unmarshal to subclass of marshaled class

使用 jackson 2.8.6你可以写一些类似的东西

With jackson 2.8.6 you can just write something like

@Test
public void readXmlToSelfDefinedPojo2() throws Exception {

    ObjectMapper mapper = new XmlMapper();
    ExtAdress pojo = mapper.readValue(
                    Thread.currentThread().getContextClassLoader().getResourceAsStream("52109685.xml"),
                    ExtAdress.class);
    System.out.println(toString(pojo));
}

public String toString(Object obj) throws JsonGenerationException, JsonMappingException, IOException{
    StringWriter w = new StringWriter();
    new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true).writeValue(w, obj);
    return w.toString();
}

它会打印

{
  "systemId" : "on the 4",
  "type" : "test"
}

为了

<?xml version="1.0" encoding="UTF-8"?>
  <RootNode_001>
<systemId>on the 4</systemId>
<systemName>give me some more</systemName>
<type>test</type>
<person>
    <firstname>James</firstname>
    <lastname>Brown</lastname>
    <address>
        <street>Funky</street>
        <city>Town</city>
        <type>HOME</type> <!-- this is the new field -->
    </address>
</person>
</RootNode_001>

@JsonIgnoreProperties(ignoreUnknown = true)
public class ExtAdress extends Adress {
    public String type;
    public ExtAdress() {
    }
}

@JsonIgnoreProperties(ignoreUnknown = true)
public class Adress {
    public String systemId;

    public Adress() {
    }
}

这篇关于Jaxb:如何在解组时替换给定对象树中的类/绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆