@Order annotation has no effect on the XML serialization order

帅比萌擦擦* 提交于 2019-12-10 15:46:37

问题


I'm using Retrofit 2 with a SimpleXmlConverter and I am facing an issue when creating a Soap Request Object, that is basically an element with 4 element children each one of them being different datatypes.

Here is the XML output I want to produce. The element order must be respected:

 <prf:container>
    <prf:aaa>111111111</prf:aaa>
    <prf:bbb>true</prf:bbb>
    <prf:element>
        <prf:ddd>50</prf:ddd>
        <prf:eee>false</prf:eee>
    </prf:element>
    <prf:ccc>textcontent</prf:ccc>
</prf:container>

Now, here is my Android Class, Container.java, representing the Soap Request Object that will be serialized:

@Root (name = "prf:container")
@Order(elements={"prf:aaa", "prf:bbb", "prf:element", "prf:ccc"})
public class Container {

    @Element (name = "prf:aaa")
    private int aaa;

    @Element(name = "prf:bbb")
    private boolean bbb;

    @Element (name = "prf:element", required = false)
    private MyElement myElement;

    @Element (name = "prf:ccc", required = false)
    private String ccc;

}

According to the Simple XML framework documentation:

By default serialization of fields is done in declaration order.

However, in Android, this is not true, at least in some cases. No matter how I set the field declaration order in my Container class, the output has always the same element order. This is a known bug and as has been reported in other SO posts.

Nonetheless, there is a solution to this issue. The Order annotation. Read more in the Javadoc.

My problem is that using the Order annotation in my case is not helping. Note that all my elements have a prefix on its name - prf:.

If I remove the prf prefix from all my element names, Order annotation will work properly, and force the XML Serialization to have the defined order. But the output elements won't have the prefix on its name.

But I really need my elements to have the prefix on its name, or else my request will have a 500 response. I also have to have the desired element order in my XML output.

Any solution to this?

Thank you


回答1:


I know it has been a long item since you posted this question but, I would like to answer your question in case anyone faced the same issue. I solved the same issue by doing the following:

For the XML document to be prepared with the elements in the order you want and if the elements have a prefix, @Order annotation might not work in some cases. In your case, the prefix 'prf' mentioned in the @Order annotation for each element would not work to order them as you desired.

"By default serialization of fields is done in declaration order."

I don't believe this either, especially when you have prefixes for elements. So, I tried changing the Java variable names. I tried naming them in alphabetical order in the same way I needed them in the generated xml. So, in your case, you can change the variable names as follows:

@Root (name = "prf:container")
public class Container {

    @Element (name = "prf:aaa")
    private int element1;

    @Element(name = "prf:bbb")
    private boolean element2;

    @Element (name = "prf:element", required = false)
    private MyElement element3;

    @Element (name = "prf:ccc", required = false)
    private String element4;

}

This would form the xml document exactly as you wanted. You might wonder that if we change the variable names to be too generic, they are not representing what they actually are but, you can always have getters and setters. For example, in your case you can have:

public void setAaa(String aaa){
    this.element1 = aaa;
}

public String getAaa(){
    return element1;
}

In the same way you can always generate the classes with alphabetically ordered variables to make sure the generated xml has the elements in the desired format.




回答2:


Maybe you using @Order with wrong syntax,Alphabetical order is not important. You can try:

@Root (name = "prf:container")
@Order(elements={"prf:container/prf:aaa", "prf:container/prf:bbb", "prf:container/prf:element", "prf:container/prf:ccc"})
public class Container {

    @Element (name = "prf:aaa")
    private int aaa;

    @Element(name = "prf:bbb")
    private boolean bbb;

    @Element (name = "prf:element", required = false)
    private MyElement myElement;

    @Element (name = "prf:ccc", required = false)
    private String ccc;
}



回答3:


SimpleXML's auto ordering by alphabetical order is working. But on one condition: the type of those fields should be the same, usually for XML it is String. It took me long time to figure that out, I had different types, and ordering by name didn't work. Since I've changed all fields to String works like a charm.

@Root(name = "sch:CheckPaymentRequest", strict = true)
public class CheckPaymentData {

@Element(name = "sch:payId")
private String Aaa1;

@Element(name = "sch:fromCurrency")
private String Bbb2;

@Element(name = "sch:fromAmount")
private String Ccc3;
...}


来源:https://stackoverflow.com/questions/35353304/order-annotation-has-no-effect-on-the-xml-serialization-order

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!