JAXB编组与XSD模式生成 - “去同步”它

时间:2012-12-12 15:57:33

标签: java jaxb xml-serialization

对于给定的类结构(跳过注释等):

class A {
 public B getObjectB {}
}

class B {
 public String getHello { return " world"; }
}

生成正确的XSD和XML输出没有问题:

<A>
 <B>
  <hello>world</hello>
 </B>
</A>

问题是,我需要稍微打破一下:首先,XSD应保持原样 - 完整。但是在编组A时,我需要得到像这样的东西:

<A>
 someStringForA
</A>

(因此B被渲染为一些计算出的字符串)。同时,在编组B(作为根)时,我仍然需要得到正常的&#34;输出

我尝试使用XmlAdapters,但使用@XmlJavaTypeAdapter也会更改XSD。通过Marshaller.setAdapter(...)设置适配器显然(http://stackoverflow.com/questions/6110757/jaxb-xml-adapters-work-via-annotations-but-not-via-setadapter/6112149#6112149)将不行。

某种解决方案是,如果有可能&#34;关闭&#34; @XmlJavaTypeAdapter(生成XSD&#34;手动&#34; JUnit,允许某些切换甚至黑客攻击)

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

注意:我是E clipseLink JAXB (MOXy)主管,也是JAXB (JSR-222)专家组的成员。

备用映射 - oxm.xml

如果您使用MOXy作为JAXB提供程序,则可以使用外部映射文件为域模型提供备用映射(请参阅: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="forum13843624">
    <java-types>
        <java-type name="A">
            <java-attributes>
                <xml-value java-attribute="objectB"/>
            </java-attributes>
        </java-type>
        <java-type name="B">
            <java-attributes>
                <xml-value java-attribute="hello"/>
            </java-attributes>
        </java-type>
    </java-types>
</xml-bindings>

Java模型

A

import javax.xml.bind.annotation.*;

@XmlRootElement(name="A")
class A {

    private B b;

    @XmlElement(name="B")
    public B getObjectB() {
        return b;
    }
    public void setObjectB(B b) {
        this.b = b;
    }

}

import javax.xml.bind.annotation.XmlElement;

class B {

    @XmlElement
    public String getHello() {
        return " world";
    }

}

<强> jaxb.properties

要将MOXy指定为JAXB提供程序,您需要在与域模型相同的包中包含名为jaxb.properties的文件,并带有以下条目(请参阅:http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html)。

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

演示代码

import java.util.*;
import javax.xml.bind.*;
import org.eclipse.persistence.jaxb.JAXBContextProperties;

public class Demo {

    public static void main(String[] args) throws Exception {
        B b = new B();
        A a = new A();
        a.setObjectB(b);

        JAXBContext jc = JAXBContext.newInstance(A.class);
        marshal(jc, a);

        Map<String, Object> properties = new HashMap<String, Object>();
        properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, "forum13843624/oxm.xml");
        JAXBContext jc2 = JAXBContext.newInstance(new Class[] {A.class}, properties);
        marshal(jc2, a);
    }

    private static void marshal(JAXBContext jc, A a) throws Exception {
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(a, System.out);
    }

}

<强>输出

以下是运行演示代码的输出。请注意同一个对象图是如何以两种不同的方式编组的。

<?xml version="1.0" encoding="UTF-8"?>
<A>
   <B>
      <hello> world</hello>
   </B>
</A>
<?xml version="1.0" encoding="UTF-8"?>
<A> world</A>