gpt4 book ai didi

c# - 使用 XmlSerializer 时如何向 XML 文件写入注释?

转载 作者:IT王子 更新时间:2023-10-29 04:38:24 25 4
gpt4 key购买 nike

我有一个对象 Foo,我将其序列化为 XML 流。

public class Foo {
// The application version, NOT the file version!
public string Version {get;set;}
public string Name {get;set;}
}

Foo foo = new Foo { Version = "1.0", Name = "Bar" };
XmlSerializer xmlSerializer = new XmlSerializer(foo.GetType());

这可以快速、轻松地完成当前所需的一切。

我遇到的问题是我需要维护一个单独的文档文件,其中包含一些小的注释。如上例所示,Name 很明显,但 Version 是应用程序版本,而不是本例中预期的数据文件版本。我还有很多类似的小事情想通过评论来澄清。

我知道如果我使用 WriteComment() 函数手动创建我的 XML 文件我可以做到这一点,但是是否有我可以实现的可能的属性或替代语法以便我可以继续使用序列化程序功能?

最佳答案

这可以通过使用返回 XmlComment 类型对象的属性来使用默认基础结构。并用 [XmlAnyElement("SomeUniquePropertyName")] 标记这些属性.

即如果像这样向 Foo 添加属性:

public class Foo
{
[XmlAnyElement("VersionComment")]
public XmlComment VersionComment { get { return new XmlDocument().CreateComment("The application version, NOT the file version!"); } set { } }

public string Version { get; set; }
public string Name { get; set; }
}

将生成以下 XML:

<Foo>
<!--The application version, NOT the file version!-->
<Version>1.0</Version>
<Name>Bar</Name>
</Foo>

但是,问题的要求不止于此,即某种在文档系统中查找评论的方法。以下代码通过使用扩展方法根据反射(reflect)的评论属性名称查找文档来实现此目的:

public class Foo
{
[XmlAnyElement("VersionXmlComment")]
public XmlComment VersionXmlComment { get { return GetType().GetXmlComment(); } set { } }

[XmlComment("The application version, NOT the file version!")]
public string Version { get; set; }

[XmlAnyElement("NameXmlComment")]
public XmlComment NameXmlComment { get { return GetType().GetXmlComment(); } set { } }

[XmlComment("The application name, NOT the file name!")]
public string Name { get; set; }
}

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class XmlCommentAttribute : Attribute
{
public XmlCommentAttribute(string value)
{
this.Value = value;
}

public string Value { get; set; }
}

public static class XmlCommentExtensions
{
const string XmlCommentPropertyPostfix = "XmlComment";

static XmlCommentAttribute GetXmlCommentAttribute(this Type type, string memberName)
{
var member = type.GetProperty(memberName);
if (member == null)
return null;
var attr = member.GetCustomAttribute<XmlCommentAttribute>();
return attr;
}

public static XmlComment GetXmlComment(this Type type, [CallerMemberName] string memberName = "")
{
var attr = 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))
return null;
return new XmlDocument().CreateComment(attr.Value);
}
}

为其生成以下 XML:

<Foo>
<!--The application version, NOT the file version!-->
<Version>1.0</Version>
<!--The application name, NOT the file name!-->
<Name>Bar</Name>
</Foo>

注意事项:

  • 扩展方法 XmlCommentExtensions.GetXmlCommentAttribute(this Type type, string memberName) 假定评论属性将被命名为 xxxXmlComment 其中 xxx 是“真正的”属性。如果是这样,它可以通过将传入的 memberName 属性标记为 CallerMemberNameAttribute 来自动确定真实的属性名称。 .这可以通过传入真实姓名手动覆盖。

  • 一旦类型和成员名称已知,扩展方法就会通过搜索应用于属性的 [XmlComment] 特性来查找相关注释。这可以替换为对单独文档文件的缓存查找。

  • 虽然仍然有必要为每个可能被注释的属性添加xxxXmlComment 属性,但这可能比implementing IXmlSerializable directly 更轻松。这非常棘手,可能导致反序列化错误,并且可能需要复杂子属性的嵌套序列化。

  • 要确保每个注释都在其关联元素之前,请参阅 Controlling order of serialization in C# .

  • 要使 XmlSerializer 序列化属性,它必须同时具有 getter 和 setter。因此,我给了评论属性 setter 什么也不做。

工作 .Net fiddle .

关于c# - 使用 XmlSerializer 时如何向 XML 文件写入注释?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7385921/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com