如何从 java 动态添加 @XmlRoot 标签?
How do I dynamically add @XmlRoot tag from java?
我有一个 JAXB 生成的 classes.The 根标签 class 是下面给出的 Foo。
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"input"
})
@XmlRootElement(name = "Foo")
public class Foo {
@XmlElement(name = "Input", required = true)
protected Too input;
public Too getInput() {
return input;
}
public void setInput(Too value) {
this.input = value;
}
}
有一个子标签 class 如下。
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Bar", propOrder = {
"request"
})
public class Bar {
@XmlElement(name = "Request", required = true)
protected List<RequestType> request;
public List<RequestType> getRequest() {
if (request == null) {
request = new ArrayList<RequestType>();
}
return this.request;
}
}
在某些情况下,我需要以 Bar 作为根 class 构造一个 xml。我使用 Jaxb marshallar 从对象转换为字符串。
public static String jaxbObjectToXMLString(Object obj) {
try {
final Marshaller m = JAXBContext.newInstance(obj.getClass()).createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
final StringWriter w = new StringWriter();
m.marshal(obj, w);
return w.toString();
} catch (JAXBException e) {
logger.error("Returning empty xml string", e);
return EMPTY_STR;
}
}
如果我提到@XmlRootElement(name = "Bar"),我可以编组。我不想在 class 中添加它,因为我不想让 Bar 始终成为我的根标签。有没有一种方法可以根据我传递的对象在 jaxbObjectToXMLString(Object obj) 中执行此操作。
if(obj instanceof Bar) { dynamically make bar as XmlRoot and generate xml}
else if(obj instanceof Foo){ marshall as it is}
通常的方法是在你的XML Schema 中定义多个xs:element 然后重新编译(xjc)。
<xs:element name="Foo" type="Foo" />
<xs:element name="Bar" type="Bar" />
@XmlRootElement 在两个 类 上没有问题。
也可以定义包装到 JAXBElement 中的根元素:
<T> JAXBElement<T> wrap( String ns, String tag, T o ){
QName qtag = new QName( ns, tag );
Class<?> clazz = o.getClass();
@SuppressWarnings( "unchecked" )
JAXBElement<T> jbe = new JAXBElement( qtag, clazz, o );
return jbe;
}
void marshal() throws Exception {
Foo foo = new Foo();
//...
JAXBElement<Foo> jbe = wrap( "", "Foo", foo );
JAXBContext jc = JAXBContext.newInstance( PACKAGE );
Marshaller m = jc.createMarshaller();
m.marshal( jbe, ... );
}
我有一个 JAXB 生成的 classes.The 根标签 class 是下面给出的 Foo。
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"input"
})
@XmlRootElement(name = "Foo")
public class Foo {
@XmlElement(name = "Input", required = true)
protected Too input;
public Too getInput() {
return input;
}
public void setInput(Too value) {
this.input = value;
}
}
有一个子标签 class 如下。
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Bar", propOrder = {
"request"
})
public class Bar {
@XmlElement(name = "Request", required = true)
protected List<RequestType> request;
public List<RequestType> getRequest() {
if (request == null) {
request = new ArrayList<RequestType>();
}
return this.request;
}
}
在某些情况下,我需要以 Bar 作为根 class 构造一个 xml。我使用 Jaxb marshallar 从对象转换为字符串。
public static String jaxbObjectToXMLString(Object obj) {
try {
final Marshaller m = JAXBContext.newInstance(obj.getClass()).createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
final StringWriter w = new StringWriter();
m.marshal(obj, w);
return w.toString();
} catch (JAXBException e) {
logger.error("Returning empty xml string", e);
return EMPTY_STR;
}
}
如果我提到@XmlRootElement(name = "Bar"),我可以编组。我不想在 class 中添加它,因为我不想让 Bar 始终成为我的根标签。有没有一种方法可以根据我传递的对象在 jaxbObjectToXMLString(Object obj) 中执行此操作。
if(obj instanceof Bar) { dynamically make bar as XmlRoot and generate xml}
else if(obj instanceof Foo){ marshall as it is}
通常的方法是在你的XML Schema 中定义多个xs:element 然后重新编译(xjc)。
<xs:element name="Foo" type="Foo" />
<xs:element name="Bar" type="Bar" />
@XmlRootElement 在两个 类 上没有问题。
也可以定义包装到 JAXBElement 中的根元素:
<T> JAXBElement<T> wrap( String ns, String tag, T o ){
QName qtag = new QName( ns, tag );
Class<?> clazz = o.getClass();
@SuppressWarnings( "unchecked" )
JAXBElement<T> jbe = new JAXBElement( qtag, clazz, o );
return jbe;
}
void marshal() throws Exception {
Foo foo = new Foo();
//...
JAXBElement<Foo> jbe = wrap( "", "Foo", foo );
JAXBContext jc = JAXBContext.newInstance( PACKAGE );
Marshaller m = jc.createMarshaller();
m.marshal( jbe, ... );
}