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

2022-09-02 22:05:03

我只是在学习JAXB(Java Architecture for XML Binding)。通过阅读一些资料,我脑海中出现了一个疑问。

甲骨文文档说:JAXBElement

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. 链接这里

这是否意味着当模式定义的数据类型和 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<ExpenseT> 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();ExpenseTJAXBElement<ExpenseT> element = factory.createExpenseReport(expense);expenseUserT user = factory.createUserT();

  1. 包装纸需要什么?JAXBElementexpense
  2. 何时使用?JAXBElement

答案 1

在一些用例中需要 a:JAXBElement

  1. 元素既是 和 。在这种情况下,映射的字段/属性是什么意思?当属性为空值时,表示该元素不存在,包装空值表示带有 的 XML 元素。nillable="true"minOccurs="0"nullJAXBElementJAXBElementxsi:nil="true"
  2. 有 2 个具有相同命名复杂类型的全局元素。由于在 JAXB 类中对应于复杂类型,因此需要一种方法来捕获遇到的根元素。有关更多详细信息,请参阅我写的这篇文章
  3. 有一种选择结构,其中一个或多个元素可以出现,并且它们是相同的类型。这里 a 是必需的,因为仅仅遇到一个值并不足以指示应该封送哪个元素。foobarJAXBElementString
  4. 在包含属性的文档中遇到 一个元素。在此示例中,与该元素对应的对象仍可以取消编组以保存属性值,但 JAXBElement 可以 stil 指示该元素为 null。xsi:nil

答案 2

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

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

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

这将工作:

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

这将抛出一个 JAXBException:

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

推荐