C# .Net XmlSerializer:将 CDATA 反序列化为内部文本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/397085/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 01:52:32  来源:igfitidea点击:

.Net XmlSerializer: deserialize CDATA being inner text

c#.netxml-serializationcdata

提问by Konstantin Spirin

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

我在使用标准 .Net XmlSerializer 进行 CDATA 反序列化时遇到问题。

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.

更新:我从外部系统获取 XML,但我无法影响它的格式,因此我无法将 CData 包含在单独的属性元素中。

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

我在这里发现了同样的问题,但没有答案: XmlSerializer、XmlAnyElement 和 CDATA

采纳答案by oefe

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

CData 属性最终为 null,因为 CDATA 部分的内容在 Data 属性中结束,在那里它被忽略...

<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.

您不应该关心外部应用程序是否将 MyClass 的内容写入为 CData。同样,外部应用程序不应该关心您如何写出它。

IOW, this should be all you need:

IOW,这应该是你所需要的:

public class MyClass
{
    string _data;

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

回答by Sebastian Castaldi

First declare a property as XmlCDataSection

首先声明一个属性为 XmlCDataSection

public XmlCDataSection ProjectXml { get; set; }

in this case projectXml is a string xml

在这种情况下,projectXml 是一个字符串 xml

ProjectXml = new XmlDocument().CreateCDataSection(projectXml);

when you serialize your message you will have your nice format (notice )

当您序列化您的消息时,您将拥有漂亮的格式(注意)

<?xml version="1.0" encoding="utf-16"?>
<MessageBase xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:type="Message_ProjectStatusChanged">
  <ID>131</ID>
  <HandlerName>Plugin</HandlerName>
  <NumRetries>0</NumRetries>
  <TriggerXml><![CDATA[<?xml version="1.0" encoding="utf-8"?><TmData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Version="9.0.0" Date="2012-01-31T15:46:02.6003105" Format="1" AppVersion="10.2.0" Culture="en-US" UserID="0" UserRole=""><PROJECT></PROJECT></TmData>]]></TriggerXml>
  <MessageCreatedDate>2012-01-31T20:28:52.4843092Z</MessageCreatedDate>
  <MessageStatus>0</MessageStatus>
  <ProjectId>0</ProjectId>
  <UserGUID>8CDF581E44F54E8BAD60A4FAA8418070</UserGUID>
  <ProjectGUID>5E82456F42DC46DEBA07F114F647E969</ProjectGUID>
  <PriorStatus>0</PriorStatus>
  <NewStatus>3</NewStatus>
  <ActionDate>0001-01-01T00:00:00</ActionDate>
</MessageBase>