views:

1202

answers:

4

I am having problems serializing a cdata section using c#

I need to serialize XmlCDataSection object property as the innertext of the element.

The result I am looking for is this:

<Test value2="Another Test">
  <![CDATA[<p>hello world</p>]]>
</Test>

To produce this, I am using this object:

public class Test
{
    [System.Xml.Serialization.XmlText()]
    public XmlCDataSection value { get; set; }

    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string value2 { get; set; }
}

When using the xmltext annotation on the value property the following error is thrown.

System.InvalidOperationException: There was an error reflecting property 'value'. ---> System.InvalidOperationException: Cannot serialize member 'value' of type System.Xml.XmlCDataSection. XmlAttribute/XmlText cannot be used to encode complex types

If I comment out the annotation, the serilization will work but the cdata section is placed into a value element which is no good for what I am trying todo:

<Test value2="Another Test">
  <value><![CDATA[<p>hello world</p>]]></value>
</Test>

Can anybody point me in the right direction to getting this to work.

Thanks, Adam

+2  A: 

The way Test is defined, your data is a CData object. So the serialisation system is trying to preserve the CData object.

But you want to serialise some text data as a CData section.

So first, the type of Test.value should be String.

You then need to control how that field is serialised, but there does not appear to be any inbuilt method or attribute to control how strings are serialised (as string, maybe with entities for reserved characters, or as CDATA). (Since, from an XML infoset perspective all of these are the same, this is not surprising.)

You can of course implemented IXmlSerializable and just code the serialisation of the Test type yourself which gives you complete control.

Richard
+1  A: 

Thanks Richard, only now had chance to get back to this. I think I have resolved the problem by using your suggestion. I have created a CDataField object using the following:

public class CDataField : IXmlSerializable
    {
        private string elementName;
        private string elementValue;

        public CDataField(string elementName, string elementValue)
        {
            this.elementName = elementName;
            this.elementValue = elementValue;
        }

        public XmlSchema GetSchema()
        {
            return null;
        }

        public void WriteXml(XmlWriter w)
        {
            w.WriteStartElement(this.elementName);
            w.WriteCData(this.elementValue);
            w.WriteEndElement();
        }

        public void ReadXml(XmlReader r)
        {                      
            throw new NotImplementedException("This method has not been implemented");
        }
    }
Adam Jenkin
A: 

I have the same issue. When I do this CDataField is used as

<CDataField><![CDATA[here is some tekst]]></CDataField>

I would like to remove the tag

<CDataField></CDataField>

Any idea how this can be done?

Thanks in advance.

Bart

Bade
John Saunders
@Bade: I second John's recommendation to ask this as a separate question (see the "Ask Question" button at the top right of each page). A separate question will be displayed on the main page of the site, so it will get a lot more views.
Bill the Lizard
If found it xmlanyelement was the solution.Now just a way to this voor non xml elements
Bade
A: 

This page has a good solution: http://www.codingspace.org/2008/03/how-to-serialize-a-string-as-cdata-in-net/

David
Here's another link with a good solution: http://stackoverflow.com/questions/1398680/xml-serialization-xmlcdatasection-as-serialization-xmltext/1607184#1607184
John Saunders