C# XML序列化-XMLCDATA节作为Serialization.XmlText
我在使用c序列化cdata节时遇到问题# 我需要将XmlCDataSection对象属性序列化为元素的innertext 我想要的结果是:C# XML序列化-XMLCDATA节作为Serialization.XmlText,c#,xml,xml-serialization,cdata,C#,Xml,Xml Serialization,Cdata,我在使用c序列化cdata节时遇到问题# 我需要将XmlCDataSection对象属性序列化为元素的innertext 我想要的结果是: <Test value2="Another Test"> <![CDATA[<p>hello world</p>]]> </Test> 在value属性上使用xmltext注释时,会引发以下错误 System.InvalidOperationException: 反映属性时出错 “值”。-->
<Test value2="Another Test">
<![CDATA[<p>hello world</p>]]>
</Test>
在value属性上使用xmltext注释时,会引发以下错误
System.InvalidOperationException:
反映属性时出错
“值”。-->
System.InvalidOperationException:
无法序列化的成员“值”
键入System.Xml.xmlcatasection。
XmlAttribute/XmlText不能用于
编码复杂类型
如果我注释掉注释,序列化将起作用,但cdata部分被放入一个value元素中,这对我尝试执行的操作没有好处:
<Test value2="Another Test">
<value><![CDATA[<p>hello world</p>]]></value>
</Test>
你好,世界]>
有谁能给我指点正确的方向,让这项工作顺利进行吗
谢谢,Adam按照
Test
的定义,您的数据是一个CData对象。因此,序列化系统试图保留CData对象
但您希望将一些文本数据序列化为CData节
因此,首先,Test.value
的类型应该是String
然后,您需要控制该字段的序列化方式,但似乎没有任何内置方法或属性来控制字符串的序列化方式(作为字符串,可能带有保留字符的实体,或作为CDATA)。(因为从XML信息集的角度来看,所有这些都是相同的,所以这并不奇怪。)
当然,您可以实现IXmlSerializable,只需自己编写
测试的序列化代码,就可以完全控制。谢谢Richard,现在才有机会回到这一点。我想我利用你的建议解决了这个问题。我使用以下方法创建了CDATA字段对象:
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");
}
}
我和亚当有同样的问题。然而,这个答案并没有100%的帮助我:)但给了我一个线索。所以我创建了如下代码。它生成的XML如下所示:
<Actions>
<Action Type="reset">
<![CDATA[
<dbname>longcall</dbname>
<ontimeout>
<url>http://[IPPS_ADDRESS]/</url>
<timeout>10</timeout>
</ontimeout>
]]>
</Action>
<Action Type="load">
<![CDATA[
<dbname>longcall</dbname>
]]>
</Action>
</Actions>
长途电话
http://[IPPS_地址]/
10
]]>
长途电话
]]>
代码:
公共类ActionsCDataField:IXmlSerializable
{
公共列表操作{get;set;}
公共操作数据字段()
{
Actions=新列表();
}
公共XmlSchema GetSchema()
{
返回null;
}
公共void WriteXml(XmlWriter w)
{
foreach(行动中的var项目)
{
w、 书面启动(“行动”);
w、 WriteAttributeString(“类型”,item.Type);
w、 WriteCData(item.InnerText);
w、 写删除();
w、 写入字符串(“\r\n”);
}
}
公共void ReadXml(XmlReader r)
{
XmlDocument xDoc=新的XmlDocument();
xDoc.荷载(r);
XmlNodeList节点=xDoc.GetElementsByTagName(“操作”);
if(nodes!=null&&nodes.Count>0)
{
foreach(节点中的XmlElement节点)
{
动作a=新动作();
a、 Type=node.GetAttribute(“Type”);
a、 InnerText=node.InnerXml;
if(a.InnerText!=null&&a.InnerText.StartsWith(“”)
a、 InnerText=a.InnerText.Substring(“.Length”);
行动.添加(a);
}
}
}
}
公共集体诉讼
{
公共字符串类型{get;set;}
公共字符串InnerText{get;set;}
}
刚刚从以下位置找到了替代方案:
Jack answer的这个基本上较短的版本具有更好的错误消息:
[XmlIgnore]
公共字符串内容{get;set;}
[XmlText]
公共XmlNode[]ContentAsCData
{
get=>new[]{new XmlDocument().CreateCataSection(内容)};
set=>Content=value?.Cast()?.Single()?.Data;
}
如果删除[XmlText]
会发生什么?它抛出A.cdata字段无法序列化,因为它没有无参数构造函数
错误
<Actions>
<Action Type="reset">
<![CDATA[
<dbname>longcall</dbname>
<ontimeout>
<url>http://[IPPS_ADDRESS]/</url>
<timeout>10</timeout>
</ontimeout>
]]>
</Action>
<Action Type="load">
<![CDATA[
<dbname>longcall</dbname>
]]>
</Action>
</Actions>
public class ActionsCDataField : IXmlSerializable
{
public List<Action> Actions { get; set; }
public ActionsCDataField()
{
Actions = new List<Action>();
}
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("<![CDATA[") && a.InnerText.EndsWith("]]>"))
a.InnerText = a.InnerText.Substring("<![CDATA[".Length, a.InnerText.Length - "<![CDATA[]]>".Length);
Actions.Add(a);
}
}
}
}
public class Action
{
public String Type { get; set; }
public String InnerText { get; set; }
}
[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;
}
}
}