3

Not sure if the title makes any sense. I have an object that I want to marshal using JAXB that looks like this:

@XmlRootElement(name = "subscriptionRequest")
    public class RegistrationRequest {

    private Long id;
    private RegistrationSource registrationSource;
    }

The RegistrationSource object:

 public class RegistrationSource {

    private Integer id;
    private String code;
}

I want to create an xml that has the following layout:

<subscriptionRequest registrationSource="0002">
    ...
</subscriptionRequest>

where the registrationSource attribute value is the code field value from the RegistrationSource object.

What xml annotations do I need to use?

Imhotep
  • 124
  • 1
  • 2
  • 7

3 Answers3

6

@XmlAttribute on registrationSource, @XmlValue on code. Note that in this case you also should have @XmlTransient on other fields of RegistrationSource, such as id

EDIT: This works:

@XmlRootElement(name = "subscriptionRequest") 
public class RegistrationRequest { 

    private Long id; 
    private RegistrationSource registrationSource; 

    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }

    @XmlAttribute
    public RegistrationSource getRegistrationSource() { return registrationSource; }
    public void setRegistrationSource(RegistrationSource registrationSource)
    {
        this.registrationSource = registrationSource;
    }
}

-

public class RegistrationSource { 

    private Integer id; 
    private String code; 

    @XmlTransient
    public Integer getId() { return id; }
    public void setId(Integer id) { this.id = id; }

    @XmlValue
    public String getCode() { return code; }
    public void setCode(String code) { this.code = code; }
}
axtavt
  • 239,438
  • 41
  • 511
  • 482
  • I get the following exception: Exception in thread "main" com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions @XmlValue is not allowed on a class that derives another class. – Imhotep Jan 21 '10 at 16:12
  • Before you write down this code I put the annotations on the fields declaration. After I saw your code and applied the changes, I get these: Exception in thread "main" com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 5 counts of IllegalAnnotationExceptions @XmlValue is not allowed on a class that derives another class. . If a class has @XmlElement property, it cannot have @XmlValue property. . @XmlAttribute/@XmlValue need to reference a Java type that maps to text in XML. . Class has two properties of the same name "registrationSource" . Class has two properties of the same name "code" – Imhotep Jan 21 '10 at 17:19
  • I guess this implementation would work only for marshal right? What if I wanted it to work for unmarshalling too? Shouldn't the annotation's be on the fields' declarations? Thanks a lot for your time. I will be able to respond to any posts by tomorrow. – Imhotep Jan 21 '10 at 17:25
  • This code works fine for both marshalling and unmarshalling (hovewer, in `RegistrationService` only `code` field is unmarshalled, because if you use `@XmlValue`, you should mark other fields `@XmlTransient`) – axtavt Jan 21 '10 at 17:42
  • I it useful to look at answer: [JaxB Unmarshalling with XmlMixed Annotation](http://stackoverflow.com/questions/23057726/jaxb-unmarshalling-with-xmlmixed-annotation) – will Jul 21 '14 at 22:56
1

If you want to generate this class automatically using some tools , then try this - Generate xsd from your xml using tools like Trang, and then generate java file from xsd using jaxb. Life would be much simpler :)

netlogger
  • 206
  • 1
  • 3
  • 7
0

The lame approach would be to add something like

@XmlAttribute(name = "registrationSource")
private String getCode() {
    return registrationSource.code;
}

to your RegistrationSource -- but there must be a more elegant way...

Rahel Lüthy
  • 6,837
  • 3
  • 36
  • 51
  • This one works, but as you say it's a bit lame. I'll wait for responses to the other suggestions and if no other possible solution is given, I will mark this as the accepted one. Thanks ps: it's like the second solution sb mentioned before you, but it seems he erased his post. – Imhotep Jan 21 '10 at 16:25
  • I have to note that in this occasion I also have to put the @XmlTransient annotation on registrationSource object, so that it doesn't show up as an element too. – Imhotep Jan 21 '10 at 16:33