XmlSerializer反序列化:内置类型的UnknownAttribute事件未触发如何解决?
问题
我为XmlSerializer的UnknownAttribute事件编写了事件处理程序,当XML文档中的自定义类型元素存在未知属性时,该事件可以正常触发,示例如下:
XML示例:
<Document> <Test unknown="attribute"> ... </Test> </Document>
对应的C#类:
public class Test { // 类成员 } public class Document { public Test Test; }
但当未知属性存在于string或List<string>等内置类型的元素上时,事件处理程序不会触发,示例如下:
XML示例:
<Document> <TestList unknown="attribute not triggered"> ... </TestList> <StringField unknown="attribute not triggered">random</StringField> </Document>
对应的C#类:
public class Document { [XmlArrayItem("Test")] public List<string> TestList; public string StringField; }
反序列化代码:
var serializer = new XmlSerializer(typeof(Document)); serializer.UnknownAttribute += HandleUnknownAttribute; using (var reader = new FileStream("filename.xml", FileMode.Open)) { serializer.Deserialize(reader); } // 事件处理程序 public void HandleUnknownAttribute(object sender, XmlAttributeEventArgs e) { // 针对TestList或StringField的未知属性不会触发此方法 }
请问如何让UnknownAttribute事件无论元素类型为何都能触发?
解决方案
要让UnknownAttribute事件对内置类型元素的未知属性也触发,核心思路是用自定义类包装内置类型,让XmlSerializer把这些元素当作自定义类型处理,具体分两种场景处理:
1. 处理单个string类型字段
创建一个包装string的自定义类,XmlSerializer处理自定义类型时,遇到未知属性就会触发UnknownAttribute事件。如果需要存储未知属性,还可以添加XmlAnyAttribute属性:
public class StringWrapper { // 可选:捕获并存储所有未知属性 [XmlAnyAttribute] public XmlAttribute[] UnknownAttributes { get; set; } // 存储实际的字符串值 [XmlText] public string Value { get; set; } } // 修改Document类,替换原string字段为包装类 public class Document { [XmlArrayItem("Test")] public List<string> TestList; public StringWrapper StringField; }
2. 处理List类型字段
复用上面的StringWrapper类,将List<string>替换为List<StringWrapper>,并调整XmlArrayItem属性指定元素类型:
// 复用StringWrapper类 public class Document { [XmlArrayItem("Test", Type = typeof(StringWrapper))] public List<StringWrapper> TestList; public StringWrapper StringField; }
修改完成后,当XML中StringField或TestList元素带有未知属性时,UnknownAttribute事件就会正常触发。即使不保留XmlAnyAttribute属性,仅用包装类也能触发事件,该属性只是用于存储捕获到的未知属性。
内容的提问来源于stack exchange,提问作者alanbi
相关产品推荐
相关产品推荐

