如何定义"描述"对于设计时类的每个XMLElement

时间:2017-08-16 12:30:53

标签: c# xml serialization xml-serialization

我有这个类,我想序列化为XML文件。我想添加一个"描述"属性如下面的类的每个属性。可能吗?或者我该如何实现这一目标?

 [Serializable]
public class Arm : INotifyPropertyChanged{

    private int _ID;
    private ArmStore _aStore;
    private ArmDimension _dimension;
    private Zone _accessibleZone;

    [XmlElement("ID")]
    [XmlAttribute("description"), Value="It defines ID number of the Arm"]
    public int ID {
        get { return _ID; }
        set { _ID = value; }
    }

    [XmlElement("Store")]
    [XmlAttribute("description"), Value="It defines the Store of the Arm"] 
   public ArmStore aStore {
        get { return _aStore; }
        set {
            _aStore = value;
            Notify("aStore");
        }
    }

    [XmlElement("Dimension")]
    [XmlAttribute("description"), Value="It defines the dimension of the Arm"]
    public ArmDimension dimension {
        get { return _dimension; }
        set {
            _dimension = value;
            Notify("dimension");
        }
    }

我希望得到以下结果:

<ID description="It defines ID number of the Arm">1</ID>
<Dimension  description="It defines the dimension of the Arm">
    <XMin>-150</XMin>
    <XMax>150</XMax>
    <YMin>-300</YMin>
    <YMax>300</YMax>
</Dimension>

提前致谢!

2 个答案:

答案 0 :(得分:1)

您可以创建自定义属性

[AttributeUsage(AttributeTargets.Property)]
public class XmlDescription : Attribute
{
    public string Value { get; set; }
}

并将其设置为所需的属性

public class Arm
{
    [XmlElement("ID")]
    [XmlDescription(Value = "It defines ID number of the Arm")]
    public int ID { get; set; }

    [XmlElement("Store")]
    [XmlDescription(Value = "It defines the Store of the Arm")]
    public ArmStore Store { get; set; }

    [XmlElement("Dimension")]
    [XmlDescription(Value = "It defines the dimension of the Arm")]
    public ArmDimension Dimension { get; set; }
}

接下来,您需要创建自定义XmlWriter

public class DescriptionWriter : XmlTextWriter
{
    public DescriptionWriter(string filename, Encoding encoding) : base(filename, encoding) { }

    public override void WriteStartElement(string prefix, string localName, string ns)
    {
        base.WriteStartElement(prefix, localName, ns);

        var prop = typeof(Arm).GetProperty(localName);
        if (prop != null)
        {
            var data = prop.GetCustomAttributesData();
            var description = data.FirstOrDefault(a => a.AttributeType == typeof(XmlDescription));
            if (description != null)
            {
                var value = description.NamedArguments.First().TypedValue.ToString().Trim('"');
                base.WriteAttributeString("description", value);
            }
        }
    }
}

此实施中存在许多缺点。特别是,属性名称和XmlElement名称必须相同。或者它不会按名称获取财产:GetProperty(localName)

按如下方式使用

Arm arm = ...

var xs = new XmlSerializer(typeof(Arm));

using (var writer = new DescriptionWriter("test.xml", Encoding.Unicode))
{
    writer.Formatting = Formatting.Indented;
    xs.Serialize(writer, arm);
}

答案 1 :(得分:0)

请尝试以下操作:

    [XmlRoot("Arm")]
    public class Arm 
    {
        [XmlElement("ID")]
        public ID id {get;set;}

        [XmlElement("Dimension")]
        public Dimension dimension { get; set;}
    }
    [XmlRoot("Dimension")]
    public class Dimension
    {
        [XmlAttribute("description")]
        public string Value { get; set; }

        [XmlElement("XMin")]
        public int XMin { get; set; }

        [XmlElement("XMax")]
        public int XMax { get; set; }

        [XmlElement("YMin")]
        public int YMin { get; set; }

        [XmlElement("YMax")]
        public int YMax { get; set; }
    }

    [XmlElement("ID")]
    public class ID
    {
        [XmlAttribute("description")]
        public string Value { get; set; }

        [XmlText]
        public int value { get; set; }
    }