以编程方式添加或设置JAXB XmlRootElement

时间:2014-08-18 03:51:59

标签: java xml jaxb

我想避免在每个用于解组xml的POJO中添加注释@XMLRootElement。有没有办法以编程方式将XmlRootElement设置或添加到类中?

 //@XmlRootElement here
    public class Person{
    private String name;
    private String address;
    //other fields
    //getters and setters here

如果不可能,如何在POJO中没有XmlRootElement的情况下解组xml?

public static <T> T unmarshal(Class clazz, String xml) {
    try {
        JAXBContext ctx = JAXBContext.newInstance(clazz);
        Unmarshaller u = ctx.createUnmarshaller();
        return (T) u.unmarshal(new StringReader(xml));
    } catch (JAXBException e) {
        throw new RuntimeException("Error interpreting XML response", e);
    }
}

没有@XmlRootElement抛出异常:

Caused by: javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"report"). Expected elements are (none)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:556)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:199)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:194)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:71)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement(UnmarshallingContext.java:962)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:399)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:380)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:101)
at org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown Source)
at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
at org.apache.xerces.impl.XMLNSDocumentScannerImpl$NSContentDispatcher.scanRootElementHook(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:195)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:168)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:137)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:194)

编辑:

Blaise的答案实际上正在发挥作用。

StreamSource source = new StreamSource(new StringReqder(xml));
return (T) u.unmarshal(source, clazz).getValue();

但是当我试图用它来返回List

//this works when I specify @XmlRootElement
private static <T> List<T> unmarshallCollection(Class<T> clazz, Source source)
            throws JAXBException {
        JAXBContext ctx = JAXBContext.newInstance(WrapperCollection.class, clazz);
        Unmarshaller u = ctx.createUnmarshaller();
        WrapperCollection<T> collection = u.unmarshal(source, WrapperCollection.class).getValue();
        return collection.getItems();
    }

并抛出异常,org.apache.xerces.dom.ElementNSImpl无法转换为.. 知道我做错了什么吗?

1 个答案:

答案 0 :(得分:1)

您只需使用unmarshal参数之一的Class方法。

StreamSource source = new StreamSource(new StringReqder(xml));
return (T) u.unmarshal(source, clazz).getValue();

注意

  • unmarshal方法的结果将是JAXBElement的一个实例,它通过调用getValue来保存您可以获取解组对象的根元素信息。
  • 对于编组,您可以通过将对象包装在JAXBElement的实例中然后封送它来提供根信息。