gpt4 book ai didi

java - "generic"真实世界文档的 JAXB 解码

转载 作者:行者123 更新时间:2023-11-30 06:28:34 25 4
gpt4 key购买 nike

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

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

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

在我最终恢复到 Xstream 之前,向社区提出一个问题:是否有一种(非 hack)方法可以在 Jaxb 中对此进行解码。到目前为止,我们尝试的是使用@XMLAdapter 进行“嵌套”解码,其中“bar”字段获取一个元素,获取目标类并调用另一个“解码”循环。这种方法 a) 相当慢 b) 随着切换到 Java 7 而被打破,其中一些神奇的 ThreadLocal 在从内部解码返回时破坏了上下文。

我发现 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 + ")";
}

}

输入.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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com