Deserializing XML with unknown fields - what will happen?

断了今生、忘了曾经 提交于 2019-12-24 08:48:39

问题


We have developed an application that "talks" to Microsoft Dynamics AX using XML. Unfortunately, the XML format isn't documented, but the guy working on the project before me simply extracted an XSD schema from the files, which we validate against when deserializing data from AX.

The only problem we have now, is that the client frequently adds new fields in AX - which naturally breaks the schema. They want us to turn off validation altogether ("We don't want to be dependent on you every time we add a new field to try something out!"), which I have advised strongly against.

But could there really be negative consequences? I.e., would the XmlSerializer actually mess up existing values, as long as only new values are added? I find it pretty much impossible to test all hypothetical scenarios, which is why I'm asking here...

A concrete example would be a format like this:

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

Suppose now they add new fields like this, but don't remove existing values:

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

Would we be able to parse A and B correctly nonetheless (in this or other variants)?

Thanks.


回答1:


Try following approach.

Define your class as follows. For each unknown field make the dictionary. Note the XmlIgnore attribute.

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

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

Subscribe to UnknownElement event.

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

In the event handler we manually read the data from the unknown elements and put it in the dictionary.

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

Deserialization is done as usual:

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


来源:https://stackoverflow.com/questions/40243841/deserializing-xml-with-unknown-fields-what-will-happen

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