如何从java动态添加@XmlRoot标记?

时间:2016-03-24 10:32:18

标签: java xml jaxb marshalling

我有一个JAXB生成的类。根标记类是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;
    }
}

下面有一个子标记类。

@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作为根类的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 =&#34; Bar&#34;)。我不想在课堂上添加这个,因为我不希望Bar总是成为我的root标签。有没有办法可以根据我传递的对象在jaxbObjectToXMLString(Object obj)中执行此操作。

if(obj instanceof Bar) { dynamically make bar as XmlRoot and generate xml}
else if(obj instanceof Foo){ marshall as it is}

1 个答案:

答案 0 :(得分:1)

通常的方法是在XML Schema中定义多个xs:元素并再次编译(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, ... );
}