@Order注释对XML序列化顺序没有影响

时间:2016-02-12 01:31:01

标签: android xml soap simple-framework retrofit2

我正在使用Retrofit 2和SimpleXmlConverter,我在创建Soap请求对象时面临一个问题,它基本上是一个包含4个元素子元素的元素,每个子元素都是不同的数据类型。

这是我想要生成的XML输出。必须遵守元素顺序:

 <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>

现在,这是我的Android类Container.java,代表将被序列化的Soap Request对象:

@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;

}

根据Simple XML框架文档:

  

默认情况下,字段序列化按声明顺序完成。

然而,在Android中,至少在某些情况下,情况并非如此。无论我如何在Container类中设置字段声明顺序,输出始终具有相同的元素顺序。这是一个已知的错误,正如其他SO帖子中所报道的那样。

尽管如此,这个问题还是有一个解决方案。 Order注释。 阅读更多in the Javadoc

我的问题是在我的案例中使用Order注释并没有帮助。请注意,我的所有元素的名称都有一个前缀 - prf:

如果我从所有元素名称中删除prf前缀,Order注释将正常工作,并强制XML序列化具有已定义的顺序。但输出元素的名称不会有前缀。

但我真的需要我的元素在其名称上加上前缀,否则我的请求将有500响应。我还必须在XML输出中拥有所需的元素顺序。

对此有任何解决方案吗?

谢谢

3 个答案:

答案 0 :(得分:6)

我知道这是一个很长的项目,因为你发布了这个问题但是,我想回答你的问题,以防任何人遇到同样的问题。我通过执行以下操作解决了同样的问题:

对于要按照所需顺序使用元素准备的XML文档,如果元素具有前缀,则@Order注释在某些情况下可能不起作用。在您的情况下,前缀&#39; prf&#39; @Order注释中提到的每个元素都无法按照您的需要对它们进行排序。

&#34;默认情况下,字段的序列化按声明顺序完成。&#34;

我也不相信这一点,特别是当你有元素的前缀时。所以,我尝试更改Java变量名称。我尝试按字母顺序命名它们,就像我在生成的xml中需要它们一样。因此,在您的情况下,您可以按如下方式更改变量名称:

@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;

}

这将完全按照您的意愿形成xml文档。您可能想知道如果我们将变量名称更改为太通用,它们并不代表它们实际上是什么,但是,您总是可以拥有getter和setter。例如,在您的情况下,您可以:

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

public String getAaa(){
    return element1;
}

以同样的方式,您始终可以使用按字母顺序排序的变量生成类,以确保生成的xml具有所需格式的元素。

答案 1 :(得分:-1)

也许您使用错误语法的@Order,字母顺序并不重要。你可以尝试:

@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;
}

答案 2 :(得分:-1)

SimpleXML按字母顺序自动排序正在运行。但在一个条件:这些字段的类型应该是相同的,通常对于XML,它是String。我花了很长时间才弄明白,我有不同的类型,按名称排序不起作用。因为我已将所有字段更改为字符串就像魅力一样。

@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;
...}