Code Reference A collection of code for my reference (and perhaps other people too)

8Mar/100

Serialization to XML with CDATA tags

Sometimes you need CDATA tags around complex text in your destination XML.

There is no build in way of doing so (that I have found).

I found this nifty CdataWrapper class on Marc Gravell's blog. Thanks Marc!

Here is the basic class.

public sealed class CDataWrapper : IXmlSerializable
{
        // implicit to/from string
        public static implicit operator string(CDataWrapper value)
        {
            return value == null ? null : value.Value;
        }
        public static implicit operator CDataWrapper(string value)
        {
            return value == null ? null : new CDataWrapper
            {
                Value =
                    value
            };
        }
        public System.Xml.Schema.XmlSchema GetSchema()
        {
            return null;
        }
        // "" => <Node/>
        // "Foo" => <Node><![CDATA[Foo]]></Node>
        public void WriteXml(XmlWriter writer)
        {
            if (!string.IsNullOrEmpty(Value))
            {
                writer.WriteCData(Value);
            }
        }
        // <Node/> => ""
        // <Node></Node> => ""
        // <Node>Foo</Node> => "Foo"
        // <Node><![CDATA[Foo]]></Node> => "Foo"
        public void ReadXml(XmlReader reader)
        {
            if (reader.IsEmptyElement)
            {
                Value = "";
            }
            else
            {
                reader.Read();
                switch (reader.NodeType)
                {
                    case XmlNodeType.EndElement:
                        Value = ""; // empty after all...
                        break;
                    case XmlNodeType.Text:
                    case XmlNodeType.CDATA:
                        Value = reader.ReadContentAsString();
                        break;
                    default:
                        throw new InvalidOperationException("Expected text/cdata");
                }
            }
        }
        // underlying value
        public string Value { get; set; }
        public override string ToString()
        {
            return Value;
        }
}

To use it, you must change your DataMember from String to CDataWrapper, make it private and give it a public property.

This:

[DataMember]
pubblic string Answer { get; set; }

Becomes this:

pubblic string Answer { get; set; }
[DataMember(Name="Answer", EmitDefaultValue=false)]
private CDataWrapper AnswerCDATA
{
    get { return Answer; }
    set { Answer = value; }
}

Then the serialization is done with one line:

.
.
.
XElement xml = Microsoft.ServiceModel.Web.SerializationExtensions.ToXml(object);
.

So simple!!!!

Comments (0) Trackbacks (0)

No comments yet.


Leave a comment


No trackbacks yet.