我们有一大套该风格的配置文档
<foo>
<bar class="com.diedel.Gnarf">
...more content
</bar>
<bar class="de.doedel.Bork">
..more content
</bar>
...
</foo>
通用实现类都是使用 Jaxb 本身映射的。
在我最终恢复到 Xstream 之前,向社区提出一个问题:是否有一种(非黑客)方法可以在 Jaxb 中对其进行解码。到目前为止,我们尝试的是使用 @XMLAdapter 进行“嵌套”解码,其中“bar”字段获取一个 Element,获取目标类并调用另一个“unmarshall”循环。这种方法 a) 相当慢,b) 在切换到 Java 7 后就被破坏了,其中一些神奇的 ThreadLocal 在从内部 unmarshall 返回时会破坏上下文。
我发现 MOXy 可能使用 @XmlDiscriminatorNode 支持这一点 - 这看起来是一个很好的解决方案,我真的很喜欢 Blaise 的非常好的输入 - 但是仅仅为了好玩而添加 >7MB 的库不是一个选择。
还有其他想法吗?
最佳答案
您可以使用 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
类:
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
下面是我根据您的问题中的示例文档使用的示例文档。我更改了包名称。
<?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>
输出
以下是运行演示代码的输出。
Gnarf(a=123)
Bork(b=Hello World)
关于java - "generic"现实世界文档的 JAXB 解码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12402215/