代码之家  ›  专栏  ›  技术社区  ›  Konstantin Spirin

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

  •  6
  • Konstantin Spirin  · 技术社区  · 17 年前

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

    使现代化 :我从外部系统获取XML,我不能影响它的格式,所以我不能将CData包含在单独的属性元素中。

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

    下面是正在序列化的类:

    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; }
        }
    }
    

    以下是失败的测试:

    [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
    }
    

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

    2 回复  |  直到 16 年前
        1
  •  10
  •   oefe    17 年前

    CData属性以null结尾,因为CData部分的内容以Data属性结尾,在Data属性中被忽略。。。

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

    绝对等同于:

    <MyClass>Hello, world!</MyClass>
    

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

    public class MyClass
    {
        string _data;
    
        [XmlText]
        public string Data
        {
            get { return _data; }
            set { _data = value; }
        }
    }
    
        2
  •  0
  •   Sebastian Castaldi    14 年前

    public XmlCDataSection ProjectXml { get; set; }
    

    在本例中,projectXml是字符串xml

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

    当你序列化你的消息时,你会得到你的好格式(注意)

    <?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>
    
    推荐文章