Скажем, у меня два JavaBeans Person
и Address
.
Если я создаю список объектов Person, я хотел бы маршалировать что-то вроде этого:
<persons>
<person>...</person>
</persons>
Можно использовать описанную здесь методику: Использование JAXB для отмены/маршалирования списка <String>
Аннотируя JaxbList с помощью @XmlRootElement(name = "persons")
и @XmlElement(name = "person")
, тогда можно перенести на XML выше.
Но было бы неплохо повторить использование одного и того же класса JaxbList<T>
, чтобы также объединить список объектов Address
. И на самом деле у меня будет много других типов beans. Я могу пойти с чем-то вроде:
<list>
<item xsi:type="person" xmlns:xsi="http://www.w2.org/2001/XmlSchema-instance"></item>
</list>
Но, в идеале, было бы неплохо, если бы он заменил "список" на множественную версию имени класса и "item" на имя класса.
Итак, возможно ли программно настроить JaxbContext или что-то во время выполнения и по существу установить значение name
внутри @XmlRootElement
и @XmlElement
?
Или любой другой способ получить эту работу без необходимости писать отдельную реализацию JaxbList
для каждого типа bean? Возможно, XmlJavaTypeAdapter может достичь такого рода вещей?
Обновление Решение @Blaise Doughan, принятое ниже, отлично работает. Для моего варианта использования мне нужно было перейти прямо из объекта 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();
}