XML中空URI命名空间元素导致反序列化数据为空的解决求助
问题:XML反序列化时因命名空间重置导致属性值为null的解决方法
问题场景
给定如下XML结构:
<?xml version="1.0" encoding="utf-8"?> <ClientInfo xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://tempuri.org/"> <Error>0</Error> <ErrorMsg /> <doc> <NewDataSet xmlns=""> <Table> <SEGMENT>123456</SEGMENT> </Table> </NewDataSet> </doc> </ClientInfo>
其中<NewDataSet xmlns="">标签将该节点及其所有子节点的默认命名空间重置为空。
使用以下C#类进行反序列化时:
[XmlRoot(ElementName = "Table")] public partial class Table { [XmlElement(ElementName = "SEGMENT")] public string SEGMENT { get; set; } } [XmlRoot(ElementName = "NewDataSet")] public partial class MyDataSet { [XmlElement(ElementName = "Table")] public Table Table { get; set; } } [XmlRoot(ElementName = "doc")] public class Doc { [XmlElement(ElementName = "NewDataSet")] public MyDataSet MyDataSet { get; set; } } [Serializable, XmlRoot(ElementName = "ClientInfo", Namespace = "http://tempuri.org/")] public partial class ClientInfo { [XmlElement(ElementName = "Error")] public int Error { get; set; } [XmlElement(ElementName = "ErrorMsg")] public object ErrorMsg { get; set; } [XmlElement(ElementName = "doc")] public Doc Doc { get; set; } }
反序列化后的对象中xmlResult.Doc.MyDataSet.Table.SEGMENT始终返回null,但移除xmlns=""属性后即可正常解析,而该属性必须保留,需要适配这种XML结构。
解决方案
问题核心是NewDataSet节点通过xmlns=""脱离了父节点的http://tempuri.org/命名空间,进入了空命名空间,但原类定义未对应声明该命名空间,导致反序列化器无法匹配节点。只需修改类的XML序列化属性,明确指定空命名空间即可:
修改后的代码如下:
[XmlRoot(ElementName = "Table", Namespace = "")] public partial class Table { [XmlElement(ElementName = "SEGMENT", Namespace = "")] public string SEGMENT { get; set; } } [XmlRoot(ElementName = "NewDataSet", Namespace = "")] public partial class MyDataSet { [XmlElement(ElementName = "Table", Namespace = "")] public Table Table { get; set; } } [XmlRoot(ElementName = "doc")] public class Doc { // 明确指定NewDataSet的命名空间为空,匹配XML中的xmlns="" [XmlElement(ElementName = "NewDataSet", Namespace = "")] public MyDataSet MyDataSet { get; set; } } [Serializable, XmlRoot(ElementName = "ClientInfo", Namespace = "http://tempuri.org/")] public partial class ClientInfo { [XmlElement(ElementName = "Error")] public int Error { get; set; } [XmlElement(ElementName = "ErrorMsg")] public object ErrorMsg { get; set; } [XmlElement(ElementName = "doc")] public Doc Doc { get; set; } }
修改后,反序列化器就能正确识别NewDataSet及其子节点的空命名空间,SEGMENT的值可正常被解析。
内容的提问来源于stack exchange,提问作者user2838376
相关产品推荐
相关产品推荐

