4

I have a class Product with the following properties: name, dateCreated, createdByUser, dateModified and modifiedByUser, and I'm using JAXB marshalling. I'd like to have output like this:

<product>
    <name>...</name>
    <auditInfo>
        <dateCreated>...</dateCreated>
        <createdByUser>...</createdByUser>
        <dateModified>...</dateModified>
        <modifiedByUser>...</modifiedByUser>
    </auditInfo>
</product>

but ideally I'd like to avoid having to create a separate AuditInfo wrapper class around these properties.

Is there a way to do this with JAXB annotations? I looked at @XmlElementWrapper but that's for collections only.

2 Answers2

3

Note: I'm the EclipseLink JAXB (MOXy) lead, and a member of the JAXB 2.X (JSR-222) expert group.

You can use MOXy's @XmlPath extension for this use case:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Product {

    private String name;

    @XmlPath("auditInfo/dateCreated/text()")
    private Date dateCreated;

    @XmlPath("auditInfo/createdByUser/text()")
    private String createdByUser;
}

For More Information:

bdoughan
  • 147,609
  • 23
  • 300
  • 400
2

No, I don't believe so. The intermediary class is necessary.

You can weasel your way around this by having AuditInfo as a nested inner class within Product, and add getter and setter methods to Product which set the fields on the AuditInfo. Clients of Product need never know.

public class Product {
   private @XmlElement AuditInfo auditInfo = new AuditInfo();

   public void setDateCreated(...) {
      auditInfo.dateCreated = ...
   }

   public static class AuditInfo {
      private @XmlElement String dateCreated;
   }
}
skaffman
  • 398,947
  • 96
  • 818
  • 769