序列化可空CDATA列表

本文关键字:列表 CDATA 序列化 | 更新日期: 2023-09-27 18:12:25

我正在尝试反序列化XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<Foos xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <FooList>
    <Foo>
      <Bar>bar value</Bar>
      <Stack />
    </Foo>
    <Foo>
      <Bar>bar value</Bar>
      <Stack><![CDATA[This is some cdata, where <br> html code is left as is..]]></Stack>
    </Foo>
  </FooList>
</Foos>

到下面的类

[XmlRoot("Foos")]
public class Foos
{
    [XmlArray("FooList")]
    [XmlArrayItem("Foo")]
    public List<Foo> FooList { get; set; }
}
public class Foo
{
    public string Bar { get; set; }
    [XmlElement("Stack", typeof(XmlCDataSection))]
    public XmlCDataSection Stack {get; set; }
}

问题是,Foos的结果FooList只包含一个(1)元素,这是第一个Foo块,Slack属性设置为null。如果我将CDATA值添加到stack,就像第二个Foo块一样,那么我将以两个元素的列表结束。

由于某些原因,在达到CDATA值为空后,反序列化停止。

我已经尝试创建一个私有字符串,并创建Stack的setter和getter,这样它使用私有属性来存储CDATA字符串。这不会改变任何东西。

有什么建议吗?

谢谢。

序列化可空CDATA列表

通过字符串获取cdata节。对象模型:

[Serializable]
[XmlRoot("Foos", Namespace="", IsNullable=false)]
public partial class Foos {
    [XmlArrayItem ("Foo", IsNullable=false)] public Foo[] FooList { get; set; } }
[Serializable] public partial class Foo {
    public string Bar { get; set; }
    [XmlIgnore] public string Stack { get; set; }
    [XmlElement("Stack", IsNullable=true)] 
    public XmlCDataSection StackCDATA {
      get { return new XmlDocument().CreateCDataSection(Stack ?? String.Empty); }
      set {
        Stack = value == null 
          ? String.Empty
          : ( String.IsNullOrWhiteSpace(value.Value)
            ? String.Empty
            : value.Value); } }
    public override string ToString() { return String.Format("Bar:{0} Stack:{1}", Bar, Stack); } }

指定null元素的正确方法是<Stack xsi:nil='true' />。有了这个补充,您的反序列化将是完美无瑕的。然而,当<Stack />第一次出现时,反序列化程序将遇到一个未知节点。如果您缺少此属性,请订阅UnknownElement:

var fooSrlz = new XmlSerializer(typeof(Foo), new XmlRootAttribute { ElementName = "Foo", IsNullable = true} );
var foosMissedByDeserializer = new List<CData.Foo>();
srlz.UnknownElement += (/*object*/ sender, /*XmlElementEventArgs  */ e) => {
    using (TextReader tr = new StringReader(e.Element.OuterXml)) {
      var foo = (CData.Foo)fooSrlz.Deserialize(tr);
      foosMissedByDeserializer.Add (foo);
    } };  

将反序列化结果与上面的foosMissedByDeserializer合并