74

I want the serialized XML output from my Java class to honor the ordering of the properties in the Java class.

It seems that JAXB orders alphabetically.

I can override this by using @XmlType with propOrder and specifying ALL of the properties, but I have a class with many properties and these are not yet finalized.

I read that specifying an empty propOrder would do it but it don't.

My example class:

package test;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlRootElement
//@XmlType(propOrder={"company", "scheme", "agreementNumber"})
@XmlType(propOrder={}) // makes no difference - still alphabetical in XML 
public class CustomerPlan2 {

    private String company;
    private String scheme;
    private String agreementNumber;

    @XmlElement(name="Company")
    public String getCompany() {
        return company;
    }
    public void setCompany(String company) {
        this.company = company;
    }

    @XmlElement(name="Scheme")
    public String getScheme() {
        return scheme;
    }
    public void setScheme(String scheme) {
        this.scheme = scheme;
    }

    @XmlElement(name="AgreementNumber")
    public String getAgreementNumber() {
        return agreementNumber;
    }
    public void setAgreementNumber(String agreementNumber) {
        this.agreementNumber = agreementNumber;
    }
}

My serialize code:

    CustomerPlan2 cp2 = new CustomerPlan2();

    cp2.setCompany("company");
    cp2.setScheme("scheme");
    cp2.setAgreementNumber("agreementnumber");
    JAXBContext context = JAXBContext.newInstance(CustomerPlan2.class);
    Marshaller marshaller = context.createMarshaller();

    marshaller.marshal(cp2, new FileWriter("C:\\temp\\out.xml"));

Output:

    <customerPlan2>
      <AgreementNumber>agreementnumber</AgreementNumber> 
      <Company>company</Company> 
      <Scheme>scheme</Scheme> 
    </customerPlan2>

I want my output to be (as the property order of my class):

    <customerPlan2>
      <Company>company</Company>
      <Scheme>scheme</Scheme> 
      <AgreementNumber>agreementnumber</AgreementNumber> 
    </customerPlan2>

Thanks for any help on this.

bobbel
  • 3,327
  • 2
  • 26
  • 43
andy hallam
  • 749
  • 1
  • 5
  • 3

9 Answers9

80

It's possible using:

@XmlType (propOrder={"prop1","prop2",..."propN"})

Just uncomment the code like this:

//@XmlType(propOrder={"company", "scheme", "agreementNumber"})

This is the correct usage.

DarthJDG
  • 16,511
  • 11
  • 49
  • 56
VIVEK PANDIAN S
  • 839
  • 6
  • 6
29

Note: I lead EclipseLink JAXB (MOXy)

The order in which Java reflection returns the list of fields/properties is not guaranteed. This is why JAXB implementations do not use it to determine element order.

By default JAXB provides no guaranteed ordering. However most (if not all JAXB implementations) use alphabetical ordering since it is deterministic. To guarantee this ordering you must annotate your class as follows:

@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)
public class Foo {
    ...
}
Pyves
  • 6,333
  • 7
  • 41
  • 59
bdoughan
  • 147,609
  • 23
  • 300
  • 400
  • 1
    Should this also work with inherited properties from your superclass? – Sébastien Tromp Dec 08 '15 at 09:52
  • I did this and got reverse alpha ordering when running the marshalling in one environment and normal alpha ordering when running the marshalling in another environment. Any thoughts/suggestions? – Achilles929 Oct 04 '16 at 21:11
5
@XmlType(propOrder={"company", "scheme", "agreementNumber"})

It's correct, but have you tried this?

@XmlType(propOrder={"Company", "Scheme", "AgreementNumber"})
nikis
  • 11,166
  • 2
  • 35
  • 45
3

This thread is old but worth throwing how I got my properties to generate xml in the proper order and NOT using alphabetical ordering as that was undesired. One thing to note is that I am using wink and jaxb which may behave differently then other providers. Wink was very specific about what was in the propertly list. Even elements I mark as xml transient, or not decorated at all were required to be part of

@XmlRootElement(name = "Product")
@XmlType(name="",propOrder={"productName","productVersion",..."propN"})

...admittedly I don't enough of WHY it works!:)

nhahtdh
  • 55,989
  • 15
  • 126
  • 162
Doug
  • 145
  • 2
  • 14
  • 1
    The name attribute in the XmlType annotation is not needed, just the propOrder attribute is enough, i.e. @XmlType(propOrder={"productName","productVersion",..."propN"}) – Michael Jan 29 '14 at 18:28
1

In @XmlType(propOrder={"prop1", "prop2"}) you can declare only propertyName you declared in the class. You cannot declare

XMLElement name (
@XmlElement(name="Company"))

in the XmlType propOrder as mentioned by above..

Dhanuka
  • 2,826
  • 5
  • 27
  • 38
gubs
  • 439
  • 3
  • 11
1

Just add :

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder={"field1", "field2", ...})
Dhanuka
  • 2,826
  • 5
  • 27
  • 38
Ryan
  • 19
  • 1
1

According to this, the order of sibling XML elements is not guaranteed.

David Weiser
  • 5,190
  • 4
  • 28
  • 35
0

This is correct : Please uncomment below line

@XmlType(propOrder={"company", "scheme", "agreementNumber"})
Umesh Bhutada
  • 301
  • 2
  • 4
-1

You have to add the propOrder and the XmlAccessType annotations to the class.

@XmlAccessorType(XmlAccessType.FIELD)

@XmlType(propOrder = {"PartyType","PartyName","PartyAddress"})
Christophe Weis
  • 2,518
  • 4
  • 28
  • 32
Don Thomas
  • 29
  • 2