对于给定的类结构(跳过注释等):
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,允许某些切换甚至黑客攻击)
感谢您的帮助!
答案 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>