How do you serialize a string as CDATA using XmlSerializer?

Viewed 91152

Is it possible via an attribute of some sort to serialize a string as CDATA using the .Net XmlSerializer?

8 Answers

In the class to be serialized:

public CData Content { get; set; }

And the CData class:

public class CData : IXmlSerializable
{
    private string _value;

    /// <summary>
    /// Allow direct assignment from string:
    /// CData cdata = "abc";
    /// </summary>
    /// <param name="value">The string being cast to CData.</param>
    /// <returns>A CData object</returns>
    public static implicit operator CData(string value)
    {
        return new CData(value);
    }

    /// <summary>
    /// Allow direct assignment to string:
    /// string str = cdata;
    /// </summary>
    /// <param name="cdata">The CData being cast to a string</param>
    /// <returns>A string representation of the CData object</returns>
    public static implicit operator string(CData cdata)
    {
        return cdata._value;
    }

    public CData() : this(string.Empty)
    {
    }

    public CData(string value)
    {
        _value = value;
    }

    public override string ToString()
    {
        return _value;
    }

    public System.Xml.Schema.XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(System.Xml.XmlReader reader)
    {
        _value = reader.ReadElementString();
    }

    public void WriteXml(System.Xml.XmlWriter writer)
    {
        writer.WriteCData(_value);
    }
}

This works pretty well

using System.Collections.ObjectModel;
using System.Linq;
using System.Xml;
using System.Xml.Serialization;

public class CDataContent
{
    public CDataContent()
    {
    }

    public CDataContent(string content)
    {
        this.Content = content;
    }

    [XmlIgnore]
    public string Content
    {
        get => this.CData.FirstOrDefault()?.Value;
        set
        {
            this.CData.Clear();
            this.CData.Add(new XmlDocument().CreateCDataSection(value));
        }
    }

    [XmlText]
    public Collection<XmlNode> CData { get; } = new();

    public static implicit operator CDataContent(string value) => new(value);

    public static implicit operator string(CDataContent value) => value.Content;
}
Related