2016-02-12 4 views
4

J'utilise Retrofit 2 avec un SimpleXmlConverter et je suis confronté à un problème lors de la création d'un objet de demande de savon, qui est essentiellement un élément avec 4 éléments enfants chacun étant différents types de données.L'annotation @Order n'a aucun effet sur l'ordre de sérialisation XML

Voici la sortie XML que je veux produire. L'ordre d'élément doit être respecté:

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

Maintenant, voici ma classe Android, Container.java, représentant le savon Demande objet qui sera publié en feuilleton:

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

} 

Selon la documentation du cadre XML simple:

Par défaut, la sérialisation des champs est effectuée dans l'ordre de déclaration.

Cependant, dans Android, ce n'est pas vrai, au moins dans certains cas. Peu importe comment je définis l'ordre de déclaration de champ dans ma classe Container, la sortie a toujours le même ordre d'éléments. Ceci est un bug connu et comme cela a été rapporté dans d'autres publications SO.

Néanmoins, il existe une solution à ce problème. L'annotation Order. En savoir plus in the Javadoc.

Mon problème est que l'utilisation de l'annotation Order dans mon cas n'aide pas. Notez que tous mes éléments ont un préfixe sur son nom - prf:.

Si je supprime le préfixe prf de tous mes noms d'éléments, l'annotation Order fonctionnera correctement et forcera la sérialisation XML à avoir l'ordre défini. Mais les éléments de sortie n'auront pas le préfixe sur son nom.

Mais j'ai vraiment besoin de mes éléments pour avoir le préfixe sur son nom, sinon ma requête aura une réponse 500. Je dois aussi avoir l'ordre d'élément désiré dans ma sortie XML.

Une solution à cela?

Merci

+0

Salut, j'ai essayé votre solution ci-dessus. Cela fonctionne bien sur les appareils avec une version Android supérieure ou égale à 5.0, mais sur les appareils ci-dessous, la commande n'est pas conservée. Pouvez-vous suggérer une solution à ce problème? –

Répondre

5

Je sais que cela a été un élément depuis longtemps que vous avez posté cette question mais je voudrais répondre à votre question au cas où quelqu'un fait face à la même question. J'ai résolu le même problème en procédant comme suit:

Pour que le document XML soit préparé avec les éléments dans l'ordre souhaité et que les éléments aient un préfixe, l'annotation @Order peut ne pas fonctionner dans certains cas. Dans votre cas, le préfixe 'prf' mentionné dans l'annotation @Order pour chaque élément ne fonctionnerait pas pour les commander comme vous le souhaitez.

"Par défaut, la sérialisation des champs est effectuée dans l'ordre de déclaration."

Je ne le crois pas non plus, surtout quand vous avez des préfixes pour les éléments. J'ai donc essayé de changer les noms des variables Java. J'ai essayé de les nommer dans l'ordre alphabétique de la même manière dont j'avais besoin d'eux dans le xml généré. Donc, dans votre cas, vous pouvez modifier les noms de variables comme suit:

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

} 

Cela formerait le document XML exactement comme vous le vouliez.Vous pourriez vous demander que si nous changeons les noms de variables pour qu'ils soient trop génériques, ils ne représentent pas ce qu'ils sont vraiment, mais vous pouvez toujours avoir des getters et des setters. Par exemple, dans votre cas, vous pouvez avoir:

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

public String getAaa(){ 
    return element1; 
} 

De la même façon, vous pouvez toujours générer les classes avec des variables classées par ordre alphabétique pour vous assurer que le fichier XML généré a les éléments dans le format souhaité.

0

Peut-être que vous utilisez @Order avec une syntaxe incorrecte, l'ordre alphabétique n'est pas important. Vous pouvez essayer:

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

La commande automatique de SimpleXML par ordre alphabétique fonctionne. Mais à une condition: le type de ces champs devrait être le même, habituellement pour XML c'est String. Il m'a fallu beaucoup de temps pour comprendre cela, j'ai eu différents types, et l'ordre par nom n'a pas fonctionné. Depuis que j'ai changé tous les champs en String fonctionne comme un charme.

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