我有一个使用命名空间来帮助反序列化存储在 XML 中的对象的应用程序。XML 命名空间也是对象所在的 C# 命名空间。例如,给定以下 XML 片段:
<xml-config xmlns:app="MyAppNS">
<app:Person>
<Name>Bill</Name>
<Car>
<Make>Honda</Make>
<Model>Accord</Model>
</Car>
</app:Person>
<app:Person>
<Name>Jane</Name>
<Car>
<Make>VW</Make>
<Model>Jetta</Model>
</Car>
</app:Person>
<app:Car>
<Make>Audi</Make>
<Model>A6</Model>
</app:Car>
</xml-config>
配置实际上只是一个随机的对象包。如您所见,顶层混合了Person
和对象。Car
我使用命名空间在加载时确定对象类型以进行正确的反序列化。这是加载文档的代码:
public static void LoadFile(String file) {
XmlDocument doc = new XmlDocument();
doc.Load(file);
XmlNode root = doc.DocumentElement;
foreach (XmlNode child in root.ChildNodes) {
if (child.NodeType != XmlNodeType.Element) {
continue;
}
Object obj = LoadObject(child);
// TODO handle object here...
}
}
private static Object LoadObject(XmlNode node) {
Object obj = null;
StringBuilder str = new StringBuilder();
if ((node.Prefix != null) && (node.Prefix != "")) {
str.Append(node.NamespaceURI).Append('.');
}
str.Append(node.LocalName);
Assembly assy = Assembly.GetExecutingAssembly();
Type type = assy.GetType(str.ToString());
XmlSerializer serdes = new XmlSerializer(type);
using (XmlNodeReader reader = new XmlNodeReader(node)) {
obj = serdes.Deserialize(reader);
}
return obj;
}
许多人马上就看到了问题,但是当使用此代码时,生成的Person
对象是空的,但是没有错误。让反序列化器填充子元素的唯一方法是为子元素使用相同的命名空间:
<app:Person>
<app:Name>Bill</app:Name>
<app:Car>
<app:Make>Honda</app:Make>
<app:Model>Accord</app:Model>
</app:Car>
</app:Person>
我尝试过的唯一其他选择是使用完全限定的类型名称作为元素名称(没有命名空间),但是我没有任何运气。有没有办法让反序列化器接受 XML 节点的非前缀子节点?