如何解决C#忽略名称空间时反序列化xml
我必须加载Xml文件并将其反序列化为对象。我可以阅读xml,到达描述对象的地步,并且仅从那很棒的那一部分解析xml,但是在xml的根中声明了一个命名空间。
我不明白为什么,但是当读取xml时,即使我从给定节点读取xmlns属性,也会将xmlns属性添加到其中,导致由于以下原因,我的程序无法将其反序列化为对象意外的成员。
我的代码:
public static SomeClass GetobjectFromXml (string path)
{
XmlReader reader = XmlReader.Create(path);
string wantednodeContents = string.Empty;
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element && reader.Name == "IWantThis")
{
wantednodeContents = reader.ReadOuterXml();
break;
}
}
XmlSerializer xmlSerializer = new XmlSerializer(typeof(SomeClass));
System.IO.StringReader stringReader = new System.IO.StringReader(wantednodeContents);
SomeClass loadedSomeClassXml = xmlSerializer.Deserialize(stringReader) as SomeClass;
return loadedSomeClassXml;
}
如何摆脱xmlns并将xml反序列化为对象?
解决方法
XDocument在反序列化任何XML时为您提供了更多的灵活性。我有一个类似的问题,可以使用下一个代码段解决:
///Type T must have a default constructor
private T XMLToObject (string pathXML)
{
T myObjectParsedFromXML= default(T);
LoadOptions loadOpt = LoadOptions.SetLineInfo;
XDocument xmlDocument = XDocument.Load(pathXML,loadOpt);
string namespaceXML = xmlDocument.Root.Name.Namespace.NamespaceName;
XmlSerializer serializer = new XmlSerializer(typeof(T),defaultNamespace: namespaceXML);
XmlReader XMLreader = xmlDocument.CreateReader();
myObjectParsedFromXML= (T)serializer.Deserialize(XMLreader);
return myObjectParsedFromXML;
}
此外,XmlSerializer为您提供了一组事件,用于注册序列化过程中的任何问题或错误:
XmlSerializer serializer = new XmlSerializer(typeof(T),defaultNamespace: namespaceXML);
serializer.UnknownAttribute += new XmlAttributeEventHandler((sender,args) =>
{
//Your code for manage the errors during serialization
});
serializer.UnknownElement += new XmlElementEventHandler((sender,args) =>
{
//Your code for manage the errors during serialization
});
,
您在这里遇到一些问题:
-
默认名称空间属性被添加到
ReadOuterXml()
返回的字符串中,因为ReadOuterXml()
旨在不改变返回的XML的语义。显然,在XML中,有一个default namespace应用于<IWantThis>
的某个父节点-作为默认名称空间,它递归地应用于<IWantThis>
本身。要保留此名称空间成员身份,ReadOuterXml()
必须在写出嵌套XML时发出默认名称空间。如果您确实要完全忽略XML上的名称空间,则需要创建自定义
所示XmlReader
,例如如 -
您需要为预期根节点为
XmlSerializer
的{{1}}构造一个SomeClass
。您可以使用XmlSerializer(Type,XmlRootAttribute)
构造函数来执行此操作,但是,如果这样做,您必须静态缓存并重用序列化程序,以避免严重的内存泄漏,如 {{3 }} 。 -
您正在创建要反序列化的元素的本地副本
<IWantThis>
,然后重新解析该本地副本。不需要这样做,您可以使用Memory Leak using StreamReader and XmlSerializer来反序列化XML的一部分。
将所有这些问题放在一起,您的wantedNodeContents
可能像这样:
GetObjectFromXml()
演示小提琴XmlReader.ReadSubtree()
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。