有没有可能以编程方式configurationJAXB?

假设我有两个JavaBeans PersonAddress

如果我创build一个Person对象的列表,我想编组到这样的东西:

 <persons> <person>...</person> </persons> 

可以使用这里描述的技术: 使用JAXB解组/编组一个List <String>

通过使用@XmlRootElement(name = "persons")@XmlElement(name = "person")@XmlRootElement(name = "persons")注释,可以编组上述XML。

但是,能够重用相同的JaxbList<T>类来编组Address对象列表也是很好的。 而实际上,我会有很多其他types的豆子。 我可以像这样做:

 <list> <item xsi:type="person" xmlns:xsi="http://www.w2.org/2001/XmlSchema-instance"></item> </list> 

但是,理想的情况是,用类名称的复数版本replace“list”并用类名replace“item”将会很好。

那么,是否有可能在运行时以编程方式configurationJaxbContext或其他东西?本质上是在@XmlRootElement@XmlElement设置name的值?

或者任何其他的方式来得到这个工作,而不必为每个beantypes编写单独的JaxbList实现? 也许XmlJavaTypeAdapter可以实现这样的事情?

更新 @Blaise下面接受的Doughan的解决scheme很好。 对于我的用例,我需要直接从Java对象到XML,下面是什么工作(注意这不是我的完整实现,它只是用于演示的伪代码):

  //JAXBContext is thread safe and so create it in constructor or //setter or wherever: ... JAXBContext jc = JAXBContext.newInstance(Wrapper.class, clazz); ... public String marshal(List<T> things, Class clazz) { //configure JAXB and marshaller Marshaller m = jc.createMarshaller(); m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); //Create wrapper based on generic list of objects Wrapper<T> wrapper = new Wrapper<T>(things); JAXBElement<Wrapper> wrapperJAXBElement = new JAXBElement<Wrapper>(new QName(clazz.getSimpleName().toLowerCase()+"s"), Wrapper.class, wrapper); StringWriter result = new StringWriter(); //marshal! m.marshal(wrapperJAXBElement, result); return result.toString(); } 

你可以像下面这样创build一个通用的Wrapper对象:

包装纸

你可以用@XmlAnyElement(lax=true)来创build一个带有List属性的通用包装类。 用于填充此列表的对象的types将基于其根元素(请参阅: http : //blog.bdoughan.com/2010/08/using-xmlanyelement-to-build-generic.html )。

 package forum13272288; import java.util.*; import javax.xml.bind.annotation.XmlAnyElement; public class Wrapper<T> { private List<T> items = new ArrayList<T>(); @XmlAnyElement(lax=true) public List<T> getItems() { return items; } } 

地址

您需要使用@XmlRootElement注释列表的可能内容。

 package forum13272288; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class Address { } 

 package forum13272288; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class Person { } 

演示

下面的演示代码演示了如何使用Wrapper类。 由于根元素可以是不同的,你将需要指定你想解包到类包装。 或者,您可以利用@XmlElementDecl批注将多个根元素与包装类关联(请参阅: http : //blog.bdoughan.com/2012/07/jaxb-and-root-elements.html )。

 package forum13272288; import javax.xml.bind.*; import javax.xml.transform.stream.StreamSource; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Wrapper.class, Person.class, Address.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); StreamSource personsXML = new StreamSource("src/forum13272288/persons.xml"); JAXBElement<Wrapper> wrapper1 = unmarshaller.unmarshal(personsXML, Wrapper.class); marshaller.marshal(wrapper1, System.out); StreamSource addressesXML = new StreamSource("src/forum13272288/addresses.xml"); JAXBElement<Wrapper> wrapper2 = unmarshaller.unmarshal(addressesXML, Wrapper.class); marshaller.marshal(wrapper2, System.out); } } 

产量

以下是运行演示代码的输出。 文件persons.xmladdresses.xml看起来就像有相应的输出。

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <persons> <person/> <person/> </persons> <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <addresses> <address/> <address/> </addresses> 

了解更多信息