使用XmlSerializer创建和使用自定义XML特殊字符

本文关键字:自定义 XML 特殊字符 XmlSerializer 创建 使用 | 更新日期: 2023-09-27 18:15:42

我有一个ColorFormat类,它存储有关颜色格式的基本信息。其目的是能够对XML进行序列化和反序列化。为了表示红色,绿色和蓝色,我使用特殊的颜色字符串标识符:

public const string RedColorIdentifier = "&red;";
public const string GreenColorIdentifier = "&green;";
public const string BlueColorIdentifier = "&blue;";

对于"#RGB"这样的格式,类格式字符串如下:

colorFormat.Format = "#" + ColorFormat.RedColorIdentifier +
                           ColorFormat.GreenColorIdentifier +
                           ColorFormat.BlueColorIdentifier;
理想情况下,序列化的XML应该是:
<ColorFormat Name="HexFmt" ColorBase="Hex">#&red;&green;&blue;</ColorFormat>

实际的序列化是:

<ColorFormat Name="HexFmt" ColorBase="Hex">#&amp;red;&amp;green;&amp;blue;</ColorFormat>

我想知道是否有一种方法可以"序列化和反序列化"您自己的自定义特殊XML字符

使用XmlSerializer创建和使用自定义XML特殊字符

可以使用CData来换行特殊字符。
来自MSDN CDATA节

例如,下面的类将通过CData包装的颜色值序列化

[XmlType("ColorFormat")]
public class ColorFormat
{
    [XmlAttribute]
    public string Name { get; set; }
    [XmlAttribute]
    public string ColorBase { get; set; }
    [XmlIgnore]
    public string Format { get; set; }
    [XmlText]
    public XmlNode[] SerializableFormat
    {
        get
        {
            var doc = new XmlDocument();
            return new XmlNode[] { doc.CreateCDataSection(this.Format) };
        }
        set
        {
            this.Format = value[0].Value;
        }
    }
}

ColorFormat类的使用

const string FORMAT = "&red;&green;&blue;";
var format = new ColorFormat
{
    Name = "HexFormat",
    ColorBase = "Hex",
    Format = FORMAT
};
var serializer = new XmlSerializer(typeof(ColorFormat));
using (var writer = new StringWriter())
{
    serializer.Serialize(writer, format);
    Console.WriteLine(writer.ToString());
}

终于找到了,必须实现IXmlSerializable如下:

public class ColorFormat : IXmlSerializable
{
    ...
    public XmlSchema GetSchema()
    {
        return null;
    }
    public void ReadXml(XmlReader reader)
    {
        Name = reader.GetAttribute(nameof(Name));
        ColorBase = CommonUtil.ParseStringToEnum<NumberBase>(reader.GetAttribute(nameof(ColorBase)));
        Format = reader.ReadInnerXml();
    }
    public void WriteXml(XmlWriter writer)
    {
        writer.WriteAttributeString(nameof(Name), Name);
        writer.WriteAttributeString(nameof(ColorBase), ColorBase.ToString());
        writer.WriteRaw(Format);
    }
}