当前位置: 首页 > 编程语言 > C#

使用XmlSerializer时如何给XML文件写注释?分享

时间:2023-04-10 14:34:03 C#

使用XmlSerializer时如何将注释写入XML文件?我有一个对象Foo,我将其序列化为XML流。publicclassFoo{//应用程序版本,而不是文件版本!publicstringVersion{get;set;}publicstringName{get;set;}}Foofoo=newFoo{Version="1.0",Name="Bar"};XmlSerializerxmlSerializer=newXmlSerializer(foo.GetType());这可以快速轻松地完成您当前需要的一切。我遇到的问题是我需要维护一个单独的文档文件,其中包含一些小注释。如上例所示,名称很明显,但版本是应用程序版本,而不是数据文件版本,正如在本例中所期望的那样。我有很多类似的小事情想通过评论来澄清。我知道如果我使用WriteComment()函数手动创建我的XML文件我可以做到这一点,但是是否有我可以实现的可能的属性或替代语法以便我可以继续使用序列化程序功能?无法使用默认基础结构。您需要为您的目的实施IXmlSerializable。非常简单的实现:publicclassFoo:IXmlSerializable{[XmlComment(Value="Theapplicationversion,NOTthefileversion!")]publicstringVersion{get;放;}公共字符串名称{得到;放;}publicvoidWriteXml(XmlWriterwriter){varproperties=GetType().GetProperties();foreach(varpropertyInfoinproperties){if(propertyInfo.IsDefined(typeof(XmlCommentAttribute),false)){writer.WriteComment(propertyInfo.GetCustomAttributes(typeof(XmlCommentAttribute),false).Cast().Single().Value);}writer.WriteElementString(propertyInfo.Name,propertyInfo.GetValue(this,null).ToString());}}publicXmlSchemaGetSchema(){thrownewNotImplementedException();}publicvoidReadXml(XmlReaderreader){thrownewNotImplementedException();}}[AttributeUsage(AttributeTargets.Property,AllowMultiple=false)]publicclassXmlCommentAttribute:Attribute{publicstringValue{get;放;}}输出:1.2A另一种方式,可能更可取:使用默认序列化程序进行序列化,然后执行后处理,即更新XML,例如使用通过使用返回XmlComment类型对象的属性并用[XmlAnyElement("SomeUniquePropertyName")]标记这些属性,您可以将默认基础结构与XDocument或XmlDocument一起使用。即,如果您像这样向Foo添加属性:}set{}}publicstringVersion{get;放;}公共字符串名称{得到;方式。以下代码通过使用扩展方法根据反映的评论属性名称查找文档来实现此目的:}set{}}[XmlComment("Theapplicationversion,NOTthefileversion!")]publicstringVersion{get;放;}[XmlAnyElement("NameXmlComment")]publicXmlCommentNameXmlComment{get{returnGetType().GetXmlComment();}set{}}[XmlComment("Theapplicationname,NOTthefilename!")]publicstringName{get;放;}}[AttributeUsage(AttributeTargets.Property,AllowMultiple=false)]publicclassXmlCommentAttribute:Attribute{publicXCommentAttribute(字符串值){this.Value=value;}公共字符串值{得到;放;}}publicstaticclassXmlCommentExtensions{conststringXmlCommentPropertyPostfix="XmlComment";staticXmlCommentAttributeGetXmlCommentAttribute(thisTypetype,stringmemberName){varmember=type.GetProperty(memberName);如果(成员==null)返回null;varattr=member.GetCustomAttribute();返回属性;}publicstaticXmlCommentGetXmlComment(thisTypetype,[CallerMemberName]stringmemberName=""){varattr=GetXmlCommentAttribute(type,memberName);if(attr==null){if(memberName.EndsWith(XmlCommentPropertyPostfix))attr=GetXmlCommentAttribute(type,memberName.Substring(0,memberName.Length-XmlCommentPropertyPostfix.Length));}if(attr==null||string.IsNullOrEmpty(attr.Value))返回null;返回新的XmlDocument().CreateComment(attr.Value);}}为它生成以下XML:1.0BarNotes:Working.Netfiddle可能晚了,但是当我尝试使用KirillPolishchuk的解决方案反序列化时,我在转换时遇到了问题。最后,我决定在序列化后编辑XML,解决方法如下:以上是C#学习教程:使用XmlSerializer时如何给XML文件写注释?如果分享的内容对你有用,需要了解更多C#学习教程,希望你多多关注——publicstaticvoidWriteXml(objectobjectToSerialize,stringpath){try{using(varw=newXmlTextWriter(path,null)){w.Formatting=Formatting.Indented;varserializer=newXmlSerializer(objectToSerialize.GetType());serializer.Serialize(w,objectToSerialize);}WriteComments(objectToSerialize,路径);}catch(Exceptione){thrownewException($"无法将xml保存到路径{path}。详细信息:{e}");}}publicstaticTReadXml(stringpath)whereT:class,new(){if(!File.Exists(path))returnnull;尝试{使用(TextReaderr=newStreamReader(path)){vardeserializer=newXmlSerializer(typeof(T));var结构=(T)解串器。反序列化(r);返回结构;}}catch(Exceptione){thrownewException($"无法从路径{path}打开和读取文件。详细信息:{e}");}}privatestaticvoidWriteComments(objectobjectToSerialize,stringpath){try{varpropertyComments=GetPropertiesAndComments(objectToSerialize);}如果(!propertyComments.Any())返回;vardoc=newXmlDocument();doc.Load(路径);varparent=doc.SelectSingleNode(objectToSerialize.GetType().Name);如果(父母==null)返回;varchildNodes=parent.ChildNodes.Cast().Where(n=>propertyComments.ContainsKey(n.Name));foreach(varchildinchildNodes){parent.InsertBefore(doc.CreateComment(propertyComments[child.Name]),child);}doc.Save(路径);}catch(Exception){//忽略}}privatestaticDictionaryGetPropertiesAndComments(objectobjectToSerialize){varpropertyComments=objectToSerialize.GetType().GetProperties().Where(p=>p.GetCustomAttributes(typeof(XmlCommentAttribute),false)。Any()).Select(v=>new{v.Name,((XmlCommentAttribute)v.GetCustomAttributes(typeof(XmlCommentAttribute),false)[0]).Value}).ToDictionary(t=>t.Name,t=>t.Value);返回属性注释;}[属性用法(AttributeTargets.Property)]publicclassXmlCommentAttribute:Attribute{publicstringValue{get;