为什么以及何时在JAXB中需要JAXBElement?

我只是在学习JAXB(用于XML绑定的Java体系结构)。 通过一些消息来源,我想到了JAXBElement一个疑问。

Oracle文档说:

When XML element information can not be inferred by the derived Java representation of the XML content, a JAXBElement object is provided. This object has methods for getting and setting the object name and object value. 链接在这里

当Schema定义的数据类型和Java数据类型之间没有直接映射时,是否需要使用JAXBElement

此外,在下面列出的一个代码示例中。 我从这里跟随:

  ObjectFactory factory = new ObjectFactory(); UserT user = factory.createUserT(); user.setUserName("Sanaulla"); ItemT item = factory.createItemT(); item.setItemName("Seagate External HDD"); item.setPurchasedOn("August 24, 2010"); item.setAmount(new BigDecimal("6776.5")); ItemListT itemList = factory.createItemListT(); itemList.getItem().add(item); ExpenseT expense = factory.createExpenseT();// we get expense object here expense.setUser(user); expense.setItems(itemList); JAXBContext context = JAXBContext.newInstance("generated"); JAXBElement element = factory.createExpenseReport(expense);//why is this required Marshaller marshaller = context.createMarshaller(); marshaller.setProperty("jaxb.formatted.output",Boolean.TRUE); marshaller.marshal(element,System.out); 

使用ExpenseT expense = factory.createExpenseT(); 我们能够获得ExpenseT对象。

如果我们看到,我们再次在代码中创建

JAXBElement element = factory.createExpenseReport(expense);
根据这个来源是expense对象的包装。
另一方面,我们不为使用检索的对象创建包装器
UserT user = factory.createUserT();

所以我的问题是:

  1. JAXBElement包装expense需要什么?
  2. 什么时候使用JAXBElement

有一些用例需要JAXBElement

  1. 元素是nillable="true"minOccurs="0" 。 在这种情况下,映射字段/属性上的null是什么意思? 当属性为JAXBElement ,null值表示该元素不存在, JAXBElement包装null表示具有xsi:nil="true"的XML元素。
  2. 有两个全局元素具有相同的命名复杂类型。 由于在JAXB类中对应于复杂类型,因此需要一种方法来捕获遇到的根元素。
  3. 有一个选择结构, foobar元素可以出现,它们是相同的类型。 这里需要JAXBElement ,因为仅仅遇到String值不足以指示应该编组哪个元素。
  4. 在包含属性的文档中遇到具有xsi:nil的元素。 在此示例中,对应于该元素的对象仍然可以被解组以保存属性值,但JAXBElement可以指示该元素为null。

JAXBElement用于在对象模型中不存在足够信息的用例中保留元素名称/命名空间。 它经常与替代组一起使用。

如果没有任何JAXB元数据,结果将被包装在JAXBElement中。 您可以使用@XmlRootElement批注来消除根级别JAXBElement。

如果您使用来自外部源的xsd文件,并且在生成的类上没有可用的XmlRootElement注释,则在编组过程中使用JAXBElement可以真正派上用场,因为您可以使用JAXBElement包装器将xml解组为对象。 你会看到指定类本身在这种情况下不起作用……

这将有效:

 JAXBElement je = (JAXBElement) unmarshaller.unmarshal(objectXML); Object = je.getValue(); 

这将抛出一个JAXBException:

 Object obj = (Object) unmarshaller.unmarshal(objectXML);