对带有未知字段的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(在这个或其他变体中)?
谢谢。
尝试以下方法。
按如下方式定义你的类。为每个未知字段制作字典。注意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);