Search code examples
javaxmljaxbmarshalling

Attribute to a JAXB Element


I'm using JAXB for creating xml. I want to set attribute 'lang' on elements PrimaryValue and AlternativeSpelling.

<AgencyOrUnit>
    <PrimaryValue lang="el">ΓΑΔΑ</PrimaryValue>
    <AlternativeSpelling lang="en">Athens General Police Directorate</AlternativeSpelling>
</AgencyOrUnit>

Here's my code:

@XmlRootElement(name = "OwnerReference")
@XmlType(propOrder = { "primaryValue", "alternativeSpelling"})
public class AgencyOrUnit {

    private String PrimaryValue;
    private String AlternativeSpelling;

    public String getPrimaryValue() {
        return PrimaryValue;
    }

    public void setPrimaryValue(String PrimaryValue){
        this.PrimaryValue = PrimaryValue;
    }

    public String getAlternativeSpelling() {
        return AlternativeSpelling;
    }

    public void setAlternativeSpelling(String AlternativeSpelling){
        this.AlternativeSpelling = AlternativeSpelling;
    }
}

Here's process of marshalling:

 AgencyOrUnit agencyOrUnit = new AgencyOrUnit();
 agencyOrUnit.setPrimaryValue("ΓΑΔΑ");
 agencyOrUnit.setAlternativeSpelling("General Police");

The problem is that I don't know how to set property with value on elements primaryValue and alternativeSpelling?


Solution

  • You can use annotations @XmlValue & @XmlAttribute but you need to create a new class to hold both lang and the original value string. Something like this:

    @Setter
    @AllArgsConstructor
    public class LocaleString {
    
        private String lang;
        private String value;
    
        @XmlAttribute
        public String getLang() {
            return lang;
        }
    
        @XmlValue
        public String getValue() {
            return value;
        }
    }
    

    Then modify your AgencyOrUnit accordingly:

    @XmlRootElement(name = "OwnerReference")
    @XmlType(propOrder = { "primaryValue", "alternativeSpelling"})
    @Getter @Setter
    public class AgencyOrUnit {
        private LocaleString PrimaryValue;
        private LocaleString AlternativeSpelling;
    }
    

    Test it:

    @Test
    void test() throws JAXBException {
        AgencyOrUnit agencyOrUnit = new AgencyOrUnit();
        agencyOrUnit.setPrimaryValue(new LocaleString("el", "ΓΑΔΑ"));
        agencyOrUnit.setAlternativeSpelling(new LocaleString("en", "General Police"));
    
        JAXBContext ctx = JAXBContext.newInstance(AgencyOrUnit.class);
    
        Marshaller marshaller = ctx.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
    
        marshaller.marshal(agencyOrUnit, System.out);
    }
    

    and you should see this:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <OwnerReference>
        <primaryValue lang="el">ΓΑΔΑ</primaryValue>
        <alternativeSpelling lang="en">General Police</alternativeSpelling>
    </OwnerReference>