如何使用 JAXB 解组包含混合标记(具有属性,并且具有嵌套标记的内容值)的 XML 文件?

How to unmarshal XML file that contains mixed tag (has attributes, and has content value with nested tag) with JAXB?

我需要将 xml 文件转换为 java 个对象。

<PRODUCT id="10" name="Notebook">
    <VALUE id="30" type="Formatted">This is mixed <TUNIT style="style-12">formatted</TUNIT> text value.</VALUE>
</PRODUCT>

这是产品 class:

@Getter
@Setter
@XmlRootElement(name = "PRODUCT")
@XmlAccessorType(XmlAccessType.FIELD)
public class Product {

    @XmlAttribute(name = "id")
    private String id;

    @XmlAttribute(name = "name")
    private String name;

    @XmlElementRef(name = "VALUE")
    private Value value;
}

这是值 class:

@Getter
@Setter
@XmlRootElement(name = "VALUE")
@XmlAccessorType(XmlAccessType.FIELD)
public class Value {

    @XmlAttribute(name = "id")
    private String id;

    @XmlAttribute(name = "type")
    private String type;

    @XmlValue
    private String content;

    @XmlElementRef(name = "TUNIT")
    private Tunit tunit;
}

这是 Tunit class:

@Getter
@Setter
@XmlRootElement(name = "TUNIT")
@XmlAccessorType(XmlAccessType.FIELD)
public class Tunit {

    @XmlAttribute(name = "style")
    private String style;

    @XmlValue
    private String content;
}

当我为 <VALUE> 属性 ID 设置 @XmlAttribute,为 <VALUE> 内容设置 @XmlValue,为 <TUNIT> 设置 @XmlElementRef - 我收到一个错误:

If a class has @XmlElement property, it cannot have @XmlValue property.

是否可以使用 JAXB 解组此 xml?

在您的 <VALUE ...>...</VALUE> 元素中您有混合内容: 纯文本和一个 <TUNIT> 元素。

因此,在你的 Value class 你需要定义一个 List<Object> 属性 接收此混合内容(在您的情况下是字符串和对象 类型 Tunit。 为此,您需要使用 @XmlMixed 对其进行注释 以及 @XmlElementRef (定义 XML <TUNIT> 和 Java Tunit 之间的映射)。 另请参阅 API documentation of @XmlMixed.

中的示例

对于您的 XML 示例 XML 片段
This is mixed <TUNIT style="style-12">formatted</TUNIT> text value.
Value 对象中的混合内容列表将收到 这些项目:

  • 一个字符串"This is mixed "
  • 一个Tunit对象
  • 一个字符串" text value."

最后 Value class 看起来像这样

@XmlRootElement(name = "VALUE")
@XmlAccessorType(XmlAccessType.FIELD)
public class Value {

    @XmlAttribute(name = "id")
    private String id;

    @XmlAttribute(name = "type")
    private String type;

    @XmlMixed
    @XmlElementRef(name = "TUNIT", type = Tunit.class)
    private List<Object> content;
}