XML序列化 – XmlCDataSection为Serialization.XmlText

我在使用c#序列化cdata部分时遇到问题

我需要将XmlCDataSection对象属性序列化为元素的innertext。

我要找的结果是这样的:

 <![CDATA[

hello world

]]>

为了产生这个,我使用这个对象:

 public class Test { [System.Xml.Serialization.XmlText()] public XmlCDataSection value { get; set; } [System.Xml.Serialization.XmlAttributeAttribute()] public string value2 { get; set; } } 

在value属性上使用xmltext注释时,将引发以下错误。

System.InvalidOperationException:反映属性’value’时出错。 —> System.InvalidOperationException:无法序列化System.Xml.XmlCDataSection类型的成员’value’。 XmlAttribute / XmlText不能用于编码复杂类型

如果我注释掉注释,序列化将起作用,但cdata部分被放入一个值元素,这对我想要做的事情没有好处:

  <![CDATA[

hello world

]]>

任何人都可以指出我正确的方向让这个工作。

谢谢,亚当

谢谢理查德,现在才有机会回到这里。 我想我已经通过你的建议解决了这个问题。 我使用以下方法创建了一个CDataField对象:

 public class CDataField : IXmlSerializable { private string elementName; private string elementValue; public CDataField(string elementName, string elementValue) { this.elementName = elementName; this.elementValue = elementValue; } public XmlSchema GetSchema() { return null; } public void WriteXml(XmlWriter w) { w.WriteStartElement(this.elementName); w.WriteCData(this.elementValue); w.WriteEndElement(); } public void ReadXml(XmlReader r) { throw new NotImplementedException("This method has not been implemented"); } } 

定义Test的方式,您的数据是CData对象。 因此序列化系统试图保留CData对象。

但是您希望将一些文本数据序列化为CData部分。

首先, Test.value的类型应该是String。

然后,您需要控制该字段的序列化方式,但似乎没有任何内置方法或属性来控制字符串的序列化方式(如字符串,可能包含保留字符的实体或CDATA)。 (因为从XML信息集的角度来看,所有这些都是相同的,这并不奇怪。)

您当然可以实现IXmlSerializable,只需自己编写Test类型的序列化,这样您就可以完全控制。

刚从here找到一个替代方案:

  [XmlIgnore] public string Content { get; set; } [XmlText] public XmlNode[] CDataContent { get { var dummy = new XmlDocument(); return new XmlNode[] {dummy.CreateCDataSection(Content)}; } set { if (value == null) { Content = null; return; } if (value.Length != 1) { throw new InvalidOperationException( String.Format( "Invalid array length {0}", value.Length)); } var node0 = value[0]; var cdata = node0 as XmlCDataSection; if (cdata == null) { throw new InvalidOperationException( String.Format( "Invalid node type {0}", node0.NodeType)); } Content = cdata.Data; } } } 

我和亚当有同样的问题。 然而这个答案并没有帮助我100%:)但给了我一个线索。 所以I’va创建了如下代码。 它生成如下XML:

   longcall  http://[IPPS_ADDRESS]/ 10  ]]>   longcall ]]>   

码:

 public class ActionsCDataField : IXmlSerializable { public List Actions { get; set; } public ActionsCDataField() { Actions = new List(); } public XmlSchema GetSchema() { return null; } public void WriteXml(XmlWriter w) { foreach (var item in Actions) { w.WriteStartElement("Action"); w.WriteAttributeString("Type", item.Type); w.WriteCData(item.InnerText); w.WriteEndElement(); w.WriteString("\r\n"); } } public void ReadXml(XmlReader r) { XmlDocument xDoc = new XmlDocument(); xDoc.Load(r); XmlNodeList nodes = xDoc.GetElementsByTagName("Action"); if (nodes != null && nodes.Count > 0) { foreach (XmlElement node in nodes) { Action a = new Action(); a.Type = node.GetAttribute("Type"); a.InnerText = node.InnerXml; if (a.InnerText != null && a.InnerText.StartsWith("")) a.InnerText = a.InnerText.Substring("".Length); Actions.Add(a); } } } } public class Action { public String Type { get; set; } public String InnerText { get; set; } }