4

我有一个很大的 XML 文件和几个 POJO 类来读取这个 XML。当我尝试使用一个 POJO 读取测试文件时,我使用这个:

    JAXBContext jaxbContext = JAXBContext.newInstance(Test.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
Test ts = (Test)jaxbUnmarshaller.unmarshal(file);
System.out.println(ts.getName());

但是当我有 30 个 POJO 时,我该怎么办?创建这 4 行 30 次?给我建议。

更新

我如何从这个例子中理解http://blog.bdoughan.com/2010/08/using-xmlanyelement-to-build-generic.html 使用我要使用的几个 POGO

JAXBContext.newInstance("message:customer:product:order");

在这个例子中,作者有 3 个 clesses,但只有其中两个他需要@XmlRootElement注释。为什么?

4

3 回答 3

6

您可以使用所有 30 个 POJO 创建 JAXBContext。您也可以将它们的名称存储在包中的 jaxb.in​​dex 索引文件中,并创建 JAXBContext.newInstance("your.package")

这是来自javadoc的有关 jaxb.in​​dex 的一些详细信息

除了在上下文路径中列出之外,程序员注释的 JAXB 映射类可以在 jaxb.in​​dex 资源文件中列出,格式如下所述。请注意,java 包可以包含模式派生类和用户注释的 JAXB 类。此外,java 包可能包含必须处理的 JAXB 包注释。(参见 JLS 第 3 版,第 7.4.1 节。“包注释”)。

您的类应该使用@XmlRootElement 或@XmlType 注释进行注释。

您还可以使用scannotation框架找到所有注释为 @XmlRootElement 的类,并使用您拥有的所有 JAXB POJO 创建 JAXBContext。

如果您有任何问题,请发表评论,我会更新答案。希望能帮助到你。

于 2012-08-20T10:18:56.557 回答
1

理想情况下,您将只创建一次 JAXBContext 并将其缓存以供重复使用。现在

但是当我有 30 个 POJO 时,我该怎么办?创建这 4 行 30 次?

如果所有 30 个 POJO 都在同一个包中(例如 com.abc),则将上下文创建为JAXBContext.newInstance("com.abc")

在这个例子中,作者有 3 个 clesses,但只有其中两个他使用 @XmlRootElement 注释。为什么?

只有与 XSD Schema 中的全局元素声明相对应的 POJO 才有@XmlRootElement注释。这是因为全局元素声明是实例文档中的潜在根元素。

如果您可以发布您的 XML 模式和 XML 实例文档的示例,以便我们提供更具体的答案,那就更好了。

于 2012-08-20T13:52:50.770 回答
1

以下应该会有所帮助。

注释

JAXB 模型类不需要任何注释。没有注释表明在创建JAXBContext.

创建一个JAXBContext

创建一个主要有两种方法JAXBContext

1 - 上课

您传入一个域类数组。然后为这些类创建映射。映射也是为引用而创建的(请参阅下面引入的类)。

2 - 关于上下文路径

您引用的我的文章 ( http://blog.bdoughan.com/2010/08/using-xmlanyelement-to-build-generic.html ) 使用上下文路径。上下文路径由冒号分隔的包名称组成。每个包必须包含一个jaxb.index文件或ObjectFactory类。该jaxb.index文件是您希望创建的类名的回车分隔列表JAXBContext。就像JAXBContext在类数组上创建 a 一样,引用类也会被处理。

开设了哪些课程

以下是创建JAXBContext.

1 - 引用的类

如果JAXBContext在类上创建了a Foo,那么Bar也将被处理,因为它被 引用Foo

@XmlAccessorType(XmlAccessType.FIELD)
public class Foo {

    private List<Bar> bar;

}

2 - 超级班

如果一个类被处理,那么它的超类也被处理。您可以将@XmlTransient注释放在一个类上以防止它被处理(参见: http ://blog.bdoughan.com/2011/06/ignoring-inheritance-with-xmltransient.html )。

public class Foo extends Bar {
}

3 - 子类

如果一个类被处理,那么它的子类不会被自动处理。您可以将@XmlSeeAlso注释放在一个类上以指定您希望处理的子类。

@XmlSeeAlso({Bar.class})
public class Foo {
}

4 - 从 JAXB 注释中引用的类

如果一个类被处理,那么在该类中的 JAXB 注释上指定的类也会被处理

public class Foo {
    @XmlElements({
         @XmlElement(name="a", type=A.class),
         @XmlElement(name="b", type=B.class)
    })
    private Object bar;
}
于 2012-08-20T18:24:48.443 回答