2

我花了一整天的时间试图找出这个问题(包括在这个网站上进行广泛的搜索),但我找不到我的问题的答案。我正在努力实现这一目标:

  • 在 XML 和一些我无法控制的现有 Java 对象之间进行转换
  • 结果/源 XML 中的元素名称与 Java 类的属性名称不同
  • 我仅限于 jaxb-2.0
  • 我可能会介绍一个可以包含注释的包装类

让我向您展示我正在努力实现的目标。假设我无法控制的 Java 类如下所示:

public class TopNoControlClass {

    private BottomNoControlClass bottomNoControlObject;

    public TopNoControlClass(BottomNoControlClass bottomNoControlObject) {
        super();
        this.bottomNoControlObject = bottomNoControlObject;
    }

    public BottomNoControlClass getBottomNoControlObject() {
        return bottomNoControlObject;
    }
    public void setBottomNoControlObject(BottomNoControlClass bottomNoControlObject) {
        this.bottomNoControlObject = bottomNoControlObject;
    }
}

和引用的类:

public class BottomNoControlClass {

    private String foo;

    public BottomNoControlClass(String foo) {
        super();
        this.foo = foo;
    }

    public String getFoo() {
        return foo;
    }
    public void setFoo(String foo) {
        this.foo = foo;
    }
}

想象一下我想把这个从编组中解脱出来:

<?xml version="1.0" encoding="UTF-8"?>
<Top>
    <Bottom>
        <bar>XXX</bar>
    </Bottom>
</Top>

<Top>将映射到TopNoControlClass并且<Bottom> Bottom 将映射到BottomNoControlClass并且<bar>将映射到BottomNoControlClass的foo属性。

为了执行上述操作,我会很乐意创建一个说明映射的外部 XML 绑定,但我想不出在运行时使用该外部绑定文件的方法。到目前为止,我看到的所有示例都只在生成时使用了外部 XML 绑定(即作为 xjc 的参数)。

我也不会遇到引入包装类的问题,该包装类将覆盖它将引用的类的类名和类属性名(即TopNoControlClassBottomNoControlClass)。使用该类构造JAXBContext并让 JAXB 完成其余工作会很容易。但我无法弄清楚该注释应该是什么样子。

任何帮助将不胜感激

雅罗斯拉夫

4

1 回答 1

0

注意: 我是EclipseLink JAXB (MOXy)负责人,也是JAXB (JSR-222)专家组的成员。

在 JAXB 2 (JSR-222) 的 MOXy 实现中,我们为这个用例提供了一个外部映射文档。

外部元数据 (oxm.xml)

以下是您的用例的映射文档的外观。出于本示例的目的,将您的模型类放在一个名为forum13318677. 有关更多信息,请参阅:http ://blog.bdoughan.com/2010/12/extending-jaxb-representing-annotations.html

<?xml version="1.0"?>
<xml-bindings
    xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="forum13318677">
    <java-types>
        <java-type name="TopNoControlClass">
            <xml-root-element name="Top"/>
            <xml-type factory-class="forum13318677.Factory" factory-method="createTopNoControlClass"/>
            <java-attributes>
                <xml-element java-attribute="bottomNoControlObject" name="Bottom"/>
            </java-attributes>
        </java-type>
        <java-type name="BottomNoControlClass">
            <xml-type factory-class="forum13318677.Factory" factory-method="createBottomNoControlClass"/>
            <java-attributes>
                <xml-element java-attribute="foo" name="bar"/>
            </java-attributes>
        </java-type>
    </java-types>
</xml-bindings>

工厂

由于您的模型类没有 0 参数构造函数,我需要创建一个工厂类(请参阅:http ://blog.bdoughan.com/2011/06/jaxb-and-factory-methods.html )。这个类是在@XmlType注解的 XML 表示中配置的。

package forum13318677;

public class Factory {

    public TopNoControlClass createTopNoControlClass() {
        return new TopNoControlClass(null);
    }

    public BottomNoControlClass createBottomNoControlClass() {
        return new BottomNoControlClass(null);
    }

}

jaxb.properties

要将 MOXy 指定为您的 JAXB (JSR-222) 提供程序,您需要包含一个jaxb.properties在与您的域类相同的包中调用的文件,其中包含以下条目(请参阅:http ://blog.bdoughan.com/2011/05/specifying- eclipselink-moxy-as-your.html)。

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

演示

下面的演示代码演示了如何利用 MOXy 的外部映射文档。请注意,即使 MOXy 用作 JAXB 提供程序,也没有对 MOXy 的编译时依赖性。

package forum13318677;

import java.io.File;
import java.util.*;
import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        Map<String, Object> properties = new HashMap<String,Object>();
        properties.put("eclipselink.oxm.metadata-source", "forum13318677/oxm.xml");
        JAXBContext jc = JAXBContext.newInstance(new Class[] {TopNoControlClass.class}, properties);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum13318677/input.xml");
        TopNoControlClass object = (TopNoControlClass) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(object, System.out);
    }

}
于 2012-11-10T11:27:43.080 回答