Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I have a problem with CDATA deserialization using standard .Net XmlSerializer.

Update: I get XML from external system and I can't influence it's format so I can't make CData be enclosed in a separate Element of Attribute.

Serialization gives this:

<?xml version="1.0" encoding="utf-16"?>
<MyClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><![CDATA[Hello, world!]]></MyClass>

Deserialization does not restore object to it's original state.

Here's class that is being serialized:

public class MyClass
{
    string _data;

    [XmlIgnore]
    public string Data
    {
        get { return _data; }
        set { _data = value; }
    }

    [XmlAnyElement]
    public XmlCDataSection CData
    {
        get { return new XmlDataDocument().CreateCDataSection(Data); }
        set { Data = value.Value; }
    }
}

Here's the test which fails:

[Test]
public void CData_as_inner_text_test()
{
    MyClass item = new MyClass();

    item.Data = "Hello, world!";

    XmlSerializer serializer = new XmlSerializer(item.GetType());
    string serialized;

    using (StringWriter sw = new StringWriter())
    {
        serializer.Serialize(sw, item);
        serialized = sw.GetStringBuilder().ToString();
    }

    MyClass deserialized;

    using (StringReader sr = new StringReader(serialized))
    {
        deserialized = (MyClass)serializer.Deserialize(sr);
    }

    Assert.AreEqual(item.Data, deserialized.Data); // For some reason, deserialized.Data == null
}

I found the same problem here but there's no answer: XmlSerializer, XmlAnyElement and CDATA

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
1.1k views
Welcome To Ask or Share your Answers For Others

1 Answer

The CData property ends up null, because the content of the CDATA section ends up in the Data property, where it is being ignored...

<MyClass><![CDATA[Hello, world!]]></MyClass>

is absolutely equivalent to:

<MyClass>Hello, world!</MyClass>

You shouldn't care whether the external app writes the content of MyClass as CData or not. Likewise, the external app shouldn't care how you write it out.

IOW, this should be all you need:

public class MyClass
{
    string _data;

    [XmlText]
    public string Data
    {
        get { return _data; }
        set { _data = value; }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...