JAXB 用点定义 XML 个元素

JAXB Define XML elements with dots

我需要创建一个匹配此结构的 XML:

<OfferPackage Name="aaa">
    <OfferPackage.Offers>
        <OfferCollection Capacity="1">
            <Offer Price="12.34"/>
            <Offer Price="12.34"/>
        </OfferCollection>
    </OfferPackage.Offers>
</OfferPackage>

我的问题是我不知道如何在此处实现:<OfferPackage.Offers>。我怎样才能只用注释得到这个“点符号”?我得到的所有内容如下所示:

<OfferPackage Name="aaa">
  <OfferCollection Capacity="1">
    <Offer Price="12.34"/>
    <Offer Price="12.34"/>
  </OfferCollection>
</OfferPackage>

这是我当前的代码:

@XmlRootElement(name = "OfferPackage")
@XmlAccessorType(XmlAccessType.FIELD)
public class OfferPackage {
    
    @XmlAttribute(name = "Name")
    private String name = null;

    @XmlElement( name = "OfferCollection")
    private List<OfferCollection> offers = null;

    @SneakyThrows
    public String toString() {
        var sw = new StringWriter();
        var marshaller = JAXBContext
                .newInstance(OfferPackage.class)
                .createMarshaller();

        marshaller.setProperty(JAXB_FRAGMENT, true);
        marshaller.marshal(this, sw);

        return sw.toString();
    }
}
@XmlRootElement(name = "Offer")
@XmlAccessorType(XmlAccessType.FIELD)
public class OfferCollection {

    @XmlAttribute(name = "Capacity")
    private Integer capacity = null;

    @XmlElement(name = "Offer")
    private List<Offer> offer = null;
}

您可以使用 @XmlElementWrapper annotation:

实现所需的行为

Generates a wrapper element around XML representation. This is primarily intended to be used to produce a wrapper XML element around collections.

在您的情况下,它看起来类似于:

@XmlRootElement(name = "OfferPackage")
@XmlAccessorType(XmlAccessType.FIELD)
public class OfferPackage {
    
    @XmlAttribute(name = "Name")
    private String name = null;

    @XmlElementWrapper(name="OfferPackage.Offers")
    @XmlElement( name = "OfferCollection")
    private List<OfferCollection> offers = null;

    @SneakyThrows
    public String toString() {
        var sw = new StringWriter();
        var marshaller = JAXBContext
                .newInstance(OfferPackage.class)
                .createMarshaller();

        marshaller.setProperty(JAXB_FRAGMENT, true);
        marshaller.marshal(this, sw);

        return sw.toString();
    }
}

另一种可能性是定义一个中间体 class、OfferPackageOffers 来包装 OfferCollection List::

@XmlRootElement(name = "OfferPackage.Offers")
@XmlAccessorType(XmlAccessType.FIELD)
public class OfferPackageOffers {

  @XmlElement( name = "OfferCollection")
  private List<OfferCollection> offers = null;

  //...
}

并在 OfferPackage 中使用新的 class 而不是提到的 OfferCollection List:

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

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

  @XmlElement( name = "OfferPackage.Offers")
  private OfferPackageOffers offers = null;

  //...

}