使用未知字段反序列化 XML - 会发生什么?
Deserializing XML with unknown fields - what will happen?
我们开发了一个应用程序 "talks" 使用 XML 到 Microsoft Dynamics AX。
不幸的是,没有记录 XML 格式,但是在我之前从事该项目的人只是从文件中提取了一个 XSD 模式,我们在从 AX 反序列化数据时根据该模式进行验证。
我们现在唯一的问题是客户端经常在 AX 中添加新字段 - 这自然会破坏架构。
他们希望我们完全关闭验证 ("We don't want to be dependent on you every time we add a new field to try something out!"),我强烈建议不要这样做。
但真的会有负面影响吗?
即,只要只添加新值,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(在这个或其他变体中)?
谢谢。
尝试以下方法。
按如下方式定义您的 class。为每个未知字段制作字典。注意 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);
我们开发了一个应用程序 "talks" 使用 XML 到 Microsoft Dynamics AX。 不幸的是,没有记录 XML 格式,但是在我之前从事该项目的人只是从文件中提取了一个 XSD 模式,我们在从 AX 反序列化数据时根据该模式进行验证。
我们现在唯一的问题是客户端经常在 AX 中添加新字段 - 这自然会破坏架构。 他们希望我们完全关闭验证 ("We don't want to be dependent on you every time we add a new field to try something out!"),我强烈建议不要这样做。
但真的会有负面影响吗? 即,只要只添加新值,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(在这个或其他变体中)?
谢谢。
尝试以下方法。
按如下方式定义您的 class。为每个未知字段制作字典。注意 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);