序列化可空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节。对象模型:
[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合并