2016-10-25 1 views
1

Nous avons développé une application qui "parle" à Microsoft Dynamics AX en utilisant XML. Malheureusement, le format XML n'est pas documenté, mais le gars travaillant sur le projet avant moi a simplement extrait un schéma XSD des fichiers, que nous validons lors de la désérialisation des données d'AX.Désérialisation de XML avec des champs inconnus - que va-t-il se passer?

Le seul problème que nous avons maintenant, c'est que le client ajoute fréquemment de nouveaux champs dans AX - ce qui brise naturellement le schéma. Ils veulent que nous désactivions complètement la validation ("Nous ne voulons pas dépendre de vous chaque fois que nous ajoutons un nouveau champ pour essayer quelque chose!"), Contre laquelle j'ai fortement déconseillé.

Mais cela pourrait-il vraiment avoir des conséquences négatives? Par exemple, est-ce que le XmlSerializer gâcherait réellement les valeurs existantes, à condition que seules les nouvelles valeurs soient ajoutées? Je trouve à peu près impossible de tester tous les scénarios hypothétiques, ce qui est la raison pour laquelle je demande ici ...

Un exemple concret serait un format comme celui-ci:

<Root> 
    <A>Foo</A> 
    <B>1234</B> 
</Root> 

Supposons maintenant, ils ajoutent de nouvelles domaines comme celui-ci, mais ne suppriment pas les valeurs existantes:

<Root> 
    <A>Foo</A> 
    <C>9876</C> 
    <B>1234</B> 
    <D>Bar</D> 
</Root> 

Est-ce que nous serons en mesure d'analyser A et B correctement quand même (dans ce ou d'autres variantes)?

Merci.

Répondre

1

Essayez l'approche suivante.

Définissez votre classe comme suit. Pour chaque champ inconnu, créez le dictionnaire. Notez l'attribut XmlIgnore.

public class Root 
{ 
    public string A { get; set; } 
    public int B { get; set; } 

    [XmlIgnore] 
    public Dictionary<string, string> Dict { get; set; } 
} 

Abonnez-vous à l'événement UnknownElement.

var xs = new XmlSerializer(typeof(Root)); 
xs.UnknownElement += Xs_UnknownElement; 

Dans le gestionnaire d'événements, nous lisons manuellement les données des éléments inconnus et les placons dans le dictionnaire.

private static void Xs_UnknownElement(object sender, XmlElementEventArgs e) 
{ 
    var root = (Root)e.ObjectBeingDeserialized; 

    if (root.Dict == null) 
     root.Dict = new Dictionary<string, string>(); 

    root.Dict.Add(e.Element.Name, e.Element.InnerText); 
} 

Désérialisation se fait comme d'habitude:

Root root; 

using (var stream = new FileStream("test.xml", FileMode.Open)) 
    root = (Root)xs.Deserialize(stream); 

Console.WriteLine(root.A); 
Console.WriteLine(root.B); 

foreach (var pair in root.Dict) 
    Console.WriteLine(pair); 
+0

Merci! Nous ne nous soucions pas des éléments inconnus. Le client veut juste que nous les ignorions. Est-il encore nécessaire de s'abonner à l'événement UnknownElement? Et cette approche fonctionnera-t-elle toujours? Que se passe-t-il s'ils (involontairement) n'envoient plus les autres champs (requis) ou ne mélangent pas la commande? Serions-nous capables de détecter cela? Ils envoient des données de facturation etc., il est donc important que nous en ayons fini correctement dans tous les cas. Merci! – TravelingFox

+0

@TravelingFox - Vous plaisantez? Ignorez simplement les éléments inconnus. 'XmlSerializer' ne leur prête aucune attention. Pas besoin de s'inscrire à l'événement. –

+0

Génial. Même s'ils dérangent l'ordre des éléments? Serait-il encore capable de détecter si des éléments manquaient? – TravelingFox