对带有未知字段的XML进行反序列化——将会发生什么?

本文关键字:什么 反序列化 未知 字段 XML | 更新日期: 2023-09-27 18:14:55

我们开发了一个使用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(在这个或其他变体中)?

谢谢。

对带有未知字段的XML进行反序列化——将会发生什么?

尝试以下方法。

按如下方式定义你的类。为每个未知字段制作字典。注意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);