XML反序列化特定命名空间匹配失败问题求助
这个问题我碰到过好几次,核心原因是XmlSerializer在匹配根元素时,没有正确识别到XML中根元素的命名空间绑定,虽然你已经给类加了XmlType属性,但还需要调整根元素的命名空间配置,同时确保子元素的命名空间也能正确匹配。
先回顾下你遇到的错误:
System.InvalidOperationException: There is an error in XML document (1, 2). ---> System.InvalidOperationException: <GetPointOfDelivery_Out xmlns='urn:webbeB2B:webservices:v0'> was not expected. at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderGetPointOfDelivery_Out.Read16_GetPointOfDelivery_Out()
1. 给根类添加XmlRoot属性
你的GetPointOfDelivery_Out类目前只设置了XmlType,但XmlType主要用于XML Schema定义,反序列化根元素时需要XmlRoot来明确指定根元素的命名空间。修改类定义如下:
[XmlRoot(Namespace = "urn:webbeB2B:webservices:v0")] [XmlType(AnonymousType = true, Namespace = "urn:webbeB2B:webservices:v0")] public class GetPointOfDelivery_Out { // 子元素必须指定相同命名空间,因为XML里的<out:POD>属于目标命名空间 [XmlElement("POD", Namespace = "urn:webbeB2B:webservices:v0")] public POD[] POD { get; set; } [XmlElement("ErrorMessage", Namespace = "urn:webbeB2B:webservices:v0")] public ErrorMessage ErrorMessage { get; set; } } // 给嵌套类也添加命名空间配置 [XmlType(Namespace = "urn:webbeB2B:webservices:v0")] public class POD { [XmlElement("PODID", Namespace = "urn:webbeB2B:webservices:v0")] public string PODID { get; set; } // 其他属性... } [XmlType(Namespace = "urn:webbeB2B:webservices:v0")] public class ErrorMessage { [XmlElement("MsgType", Namespace = "urn:webbeB2B:webservices:v0")] public string MsgType { get; set; } // 其他属性... }
2. (可选)创建XmlSerializer时显式指定命名空间
如果不想修改类的属性,也可以在实例化XmlSerializer时,通过构造函数重载直接指定默认命名空间:
var xmlSerializer = new XmlSerializer(typeof(GetPointOfDelivery_Out), "urn:webbeB2B:webservices:v0"); using (var textReader = new StringReader(xml)) { return (GetPointOfDelivery_Out)xmlSerializer.Deserialize(textReader); }
问题根源解析
XML中的前缀out:只是命名空间urn:webbeB2B:webservices:v0的别名,XmlSerializer真正关心的是元素的命名空间URI,而不是前缀。你之前的代码只通过XmlType指定了类型的命名空间,但根元素的命名空间匹配需要XmlRoot(或序列化时指定的默认命名空间)来明确,否则XmlSerializer会默认期望根元素没有命名空间,从而抛出“不符合预期”的错误。
另外,XML中的子元素(比如POD、MsgType)都属于同一个命名空间,所以必须在对应的XmlElement属性或类的XmlType中指定相同的命名空间,否则反序列化时这些子元素会被忽略或触发新的错误。
内容的提问来源于stack exchange,提问作者Steven

