JAXB解组“通用”真实世界文档

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

  ...more content   ..more content  ...  

通用实现类都使用Jaxb本身进行映射。

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

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

其他想法?

您可以使用JAXB(JSR-222)StAX(JSR-173)执行以下操作

演示

StAX XMLStreamReader可用于解析XML文档。 您可以使用它前进到bar元素,然后您可以读取class属性并从ClassLoader适当的Java类。 然后,您可以利用其中一个带有类参数的unmarshal方法。

 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课程的示例。

 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中

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

    123   Hello World   

产量

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

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

如果结构真的那么简单,我会尝试使用XMLStreamReader解析前两个级别(foo和bar的class属性),然后将读取器交给JAXB unmarshaller来解析每个条形,将结果汇总到一个列表。 我不打算尝试直接使用JAXB解析外包层。