JAXB解组“泛型”现实世界的文件 [英] JAXB unmarshalling of "generic" real world documents

查看:327
本文介绍了JAXB解组“泛型”现实世界的文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一大堆风格的配置文件

We have a large set of configuration documents of the style

<foo>
  <bar class="com.diedel.Gnarf">
    ...more content
  </bar>
  <bar class="de.doedel.Bork">
    ..more content
  </bar>
  ...
</foo>

通用实现类都是使用Jaxb自己映射的。

The generic implementation classes are all mapped using Jaxb themselves.

在我最终回归到Xstream之前,向社区提出一个问题:是否有一种(非黑客)方式可以在Jaxb中解组。到目前为止我们尝试使用@XMLAdapter进行嵌套解组,其中bar字段获取Element,获取目标类并调用另一个unmarshall循环。这种方法已经a)非常缓慢,并且b)在切换到Java 7时被破坏,其中一些神奇的ThreadLocal在从内部unmarshall返回时破坏了上下文。

Before i finally revert to Xstream, a question to the community: Is there a (non hack) way to get this unmarshalled in Jaxb. What we tried so far is "nested" unmarshalling using an @XMLAdapter, where the "bar" field gets an Element, gets the target class and calls another "unmarshall" cycle. This approach has been a) quite slow and b) is broken with the switch to Java 7 where some magic ThreadLocal destroys the context when returning from the inner unmarshall.

我发现MOXy可以使用@XmlDiscriminatorNode来支持这个 - 这看起来是一个很好的解决方案,我非常喜欢Blaise的非常好的输入 - 但是为了好玩而添加> 7MB的lib不是一种选择。

I found that MOXy may support this using @XmlDiscriminatorNode - this looks like a good solution and i really like the very good input of Blaise - but adding a >7MB lib just for fun is not an option.

其他想法?

推荐答案

您可以使用 JAXB(JSR-222) StAX(JSR-173)

You could do something like the following with JAXB (JSR-222) and StAX (JSR-173):

演示

可以使用StAX XMLStreamReader 来解析XML文档。您可以使用它前进到 bar 元素,然后您可以读取属性并加载相应的Java类来自 ClassLoader 。然后你可以利用一个带有类参数的 unmarshal 方法。

A StAX XMLStreamReader can be used to parse the XML document. You can use it to advance to a bar element, then you can read the class attribute and load the appropriate Java class from a ClassLoader. Then you can leverage one of the unmarshal methods that takes a class parameter.

package forum12402215;

import javax.xml.bind.*;
import javax.xml.stream.*;
import javax.xml.transform.stream.StreamSource;

public class Demo {

    public static void main(String[] args) throws Exception {
        ClassLoader classLoader = Bork.class.getClassLoader();
        JAXBContext jc = JAXBContext.newInstance(Bork.class, Gnarf.class);
        Unmarshaller unmarshaller = jc.createUnmarshaller();

        StreamSource source = new StreamSource("src/forum12402215/input.xml");
        XMLInputFactory xif = XMLInputFactory.newFactory();
        XMLStreamReader xsr = xif.createXMLStreamReader(source);
        xsr.nextTag(); // Advance to "foo" element
        xsr.nextTag(); // Advance to "bar" element

        while(xsr.getLocalName().equals("bar")) {
             String className = xsr.getAttributeValue("", "class");
             Class<?> clazz = classLoader.loadClass(className);
             Object object = unmarshaller.unmarshal(xsr, clazz).getValue();
             System.out.println(object);
             xsr.nextTag();
        }
    }

}

Bork

下面是一个示例 Bork 类。

package forum12402215;

public class Bork {

    private String b;

    public String getB() {
        return b;
    }

    public void setB(String b) {
        this.b = b;
    }

    @Override
    public String toString() {
        return "Bork(b=" + b + ")";
    }

}

Gnarf

下面是一个示例 Gnarf 类:

package forum12402215;

public class Gnarf {

    private int a;

    public int getA() {
        return a;
    }

    public void setA(int a) {
        this.a = a;
    }

    @Override
    public String toString() {
        return "Gnarf(a=" + a + ")";
    }

}

input.xml

以下是我根据您的问题使用的示例文档。我更改了包名。

Below is he sample document I used used for this example based on the one from your question. I changed the package names.

<?xml version="1.0" encoding="UTF-8"?>
<foo>
    <bar class="forum12402215.Gnarf">
        <a>123</a>
    </bar>
    <bar class="forum12402215.Bork">
        <b>Hello World</b>
    </bar>
</foo>

输出

以下是运行演示代码的输出。

Below is the output from running the demo code.

Gnarf(a=123)
Bork(b=Hello World)

这篇关于JAXB解组“泛型”现实世界的文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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