如何在没有任何相关信息的情况下通过 JAXB 封送对象?

2022-09-03 18:32:56

我有一个对象 ,它是某种类型的,要么是-注释的,要么不是。我想将其封送到 XML 中:value@XmlRootElement

String value1 = "test";
assertEquals("<foo>test</foo>", toXml("foo", value1));
// ...
@XmlRootElement
class Bar {
  public String bar = "test";
}
assertEquals("<foo><bar>test</bar></foo>", toXml("foo", new Bar()));

我可以使用 JAXB 现有工具执行此操作,还是应该创建一些自定义分析器?


答案 1

您可以利用 JAXBIntrospector 执行以下操作:

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBIntrospector;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.namespace.QName;

public class Demo {


    public static void main(String[] args) throws Exception {
        Object value = "Hello World";
        //Object value = new Bar();

        JAXBContext jc = JAXBContext.newInstance(String.class, Bar.class);
        JAXBIntrospector introspector = jc.createJAXBIntrospector();
        Marshaller marshaller = jc.createMarshaller();
        if(null == introspector.getElementName(value)) {
            JAXBElement jaxbElement = new JAXBElement(new QName("ROOT"), Object.class, value);
            marshaller.marshal(jaxbElement, System.out);
        } else {
            marshaller.marshal(value, System.out);
        }
    }

    @XmlRootElement
    public static class Bar {

    }

}

使用上述代码,当 JAXBElement 被编组时,它将使用与相应的模式类型对应的 xsi:type 属性进行限定:

<ROOT 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string">Hello World</ROOT>

要消除限定条件,您只需将创建 JAXBElement 的行更改为:

JAXBElement jaxbElement = new JAXBElement(new QName("ROOT"), value.getClass(), value);

这将生成以下 XML:

<ROOT>Hello World</ROOT>

答案 2

这是如何封送,这是一个.您可以传递给构造函数,并且:value1StringyourObject.getClass()JAXBElementvalue1

try {
    JAXBContext jc = JAXBContext.newInstance();
    Marshaller m = jc.createMarshaller();
    String value1 = "test";
    JAXBElement jx = new JAXBElement(new QName("foo"), value1.getClass(), value1);
    m.marshal(jx, System.out);
} catch (JAXBException ex) {
    ex.printStackTrace();
}

这无需使用 .上述代码的结果是:@XmlRootElement

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo>test</foo>

另一方面,这不适用于对象:。但是,您可以从内部获取值,并用它来创建值,而不是对象本身。Barjavax.xml.bind.JAXBException: myPackage.Bar is not known to this contextBarJAXBElement


推荐