JAXB unmarshaller.unmarshal 何时返回 JAXBElement<MySchemaObject> 或 MySchemaObject?

2022-09-01 12:01:23

我有两个代码,在两个不同的java项目中,做几乎相同的事情,(根据xsd文件取消Web服务的输入)。

但是在一种情况下,我应该这样写:(输入是占位符名称)(元素是OMElement输入)

ClassLoader clInput = input.ObjectFactory.class.getClassLoader();
JAXBContext jc = JAXBContext.newInstance("input", clInput);
Unmarshaller unmarshaller = jc.createUnmarshaller();
Input input = (Input)unmarshaller.unmarshal( element.getXMLStreamReader() );

在另一个库中,我必须使用JAXBElement.getValue(),因为它是返回的JAXBElement,并且简单的(输入)转换只是崩溃:

Input input = (Input)unmarshaller.unmarshal( element.getXMLStreamReader() ).getValue();

你知道是什么导致了这样的差异吗?


答案 1

如果根元素与 Java 类唯一对应,则将返回该类的实例,如果不是,则返回 a。JAXBElement

如果要确保始终获取域对象的实例,则可以利用 .下面是一个示例。JAXBInstrospector

演示

package forum10243679;

import java.io.StringReader;
import javax.xml.bind.*;
import javax.xml.transform.stream.StreamSource;

public class Demo {

    private static final String XML = "<root/>";

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Root.class);
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        JAXBIntrospector jaxbIntrospector = jc.createJAXBIntrospector();

        Object object = unmarshaller.unmarshal(new StringReader(XML));
        System.out.println(object.getClass());
        System.out.println(jaxbIntrospector.getValue(object).getClass());

        Object jaxbElement = unmarshaller.unmarshal(new StreamSource(new StringReader(XML)), Root.class);
        System.out.println(jaxbElement.getClass());
        System.out.println(jaxbIntrospector.getValue(jaxbElement).getClass());
    }

}

输出

class forum10243679.Root
class forum10243679.Root
class javax.xml.bind.JAXBElement
class forum10243679.Root

答案 2

这取决于根元素类上是否存在 XmlRootElement 批注

如果从 XSD 生成 JAXB 类,那么将应用以下规则:

  • 如果根元素的类型是匿名类型 ->则将 XmlRootElement 注释添加到生成的类中
  • 如果根元素的类型是顶级类型 ->则从生成的类中省略 XmlRootElement 注释

出于这个原因,我经常为根元素选择匿名类型。

您可以使用自定义文件自定义此匿名类型的类名。例如,创建一个绑定.xjc文件,如下所示:

<jxb:bindings version="1.0"
              xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
              xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <jxb:bindings schemaLocation="yourXsd.xsd" node="/xs:schema">
        <jxb:bindings  node="//xs:element[@name='yourRootElement']">
            <jxb:class name="YourRootElementType"/>
        </jxb:bindings> 
    </jxb:bindings>
</jxb:bindings>

推荐