使用未知字段反序列化XML - 会发生什么?

时间:2016-10-25 15:23:46

标签: c# .net xmlserializer

我们开发了一个应用程序"会谈"使用XML到Microsoft Dynamics AX。 遗憾的是,XML格式没有记录,但是在我之前处理项目的人只是从文件中提取了一个XSD架构,我们在从AX反序列化数据时对其进行了验证。

我们现在唯一的问题是,客户端经常在AX中添加新字段 - 这自然会破坏架构。 他们希望我们完全关闭验证("我们不想在每次添加新字段时都依赖于您来尝试一些事情!"),我强烈反对。

但真的会有负面影响吗? 即,只要添加新值,XmlSerializer实际上是否会破坏现有值? 我发现测试所有假设情景几乎是不可能的,这就是我在这里问的原因......

一个具体的例子是这样的格式:

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

现在假设他们添加了这样的新字段,但不删除现有值:

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

我们能否正确地解析A和B(在这个或其他变体中)?

感谢。

1 个答案:

答案 0 :(得分:1)

尝试以下方法。

按如下方式定义您的课程。对于每个未知字段制作字典。请注意XmlIgnore属性。

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

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

订阅UnknownElement活动。

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

在事件处理程序中,我们手动从未知元素中读取数据并将其放入字典中。

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

反序列化照常完成:

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