自定义 XML 序列化和处理 CDATA
Custom XML Serialization and handling CDATA
我有一个自定义 XML 序列化器,如下所示
public void WriteXml(XmlWriter writer)
{
foreach (PropertyInfo pi in this.GetType().GetProperties())
{
if (pi.GetCustomAttributes(typeof(XmlIgnoreAttribute), true).Count() == 0)
{
var attrList = pi.GetCustomAttributes(typeof(XmlElementAttribute), true);
if (attrList.Count() > 0)
{
XmlElementAttribute xe = (XmlElementAttribute)attrList[0];
writer.WriteStartElement(xe.ElementName);
}
else
{
writer.WriteStartElement(pi.Name);
}
if (pi.PropertyType == typeof(int) || (pi.PropertyType == typeof(float)))
{
writer.WriteString(pi.GetValue(this, null).ToString());
}
else if (pi.PropertyType == typeof(DateTime))
{
DateTime dt = (DateTime)(pi.GetValue(this, null));
writer.WriteString(dt.ToString("yyyyMMddHHmm"));
}
else
{
if (pi.GetValue(this, null) == null) writer.WriteString(String.Empty);
else
{
// write code to generate CDATA
String val = pi.GetValue(this, null).ToString();
if (val.IndexOfAny(invalidChars) != -1)
writer.WriteString(String.Format(@"<![CDATA[{0}]]>", pi.GetValue(this, null).ToString()));
else writer.WriteString(pi.GetValue(this, null).ToString());
}
}
writer.WriteEndElement();
}
}
}
}
}
当值包含在 XML 值中无效的字符之一时,就会出现问题。使用这些行已成功检测到
if (val.IndexOfAny(invalidChars) != -1)
writer.WriteString(String.Format(@"<![CDATA[{0}]]>", pi.GetValue(this, null).ToString()));
else writer.WriteString(pi.GetValue(this, null).ToString());
问题是 CDATA 的创建——我得到的不是格式正确的 CDATA,而是 > > ;和 < ;
那么您应该如何在自定义序列化程序中创建格式正确的 CDATA?
Jeroen Mostert 在评论中提供的答案。
替换以下代码
if (val.IndexOfAny(invalidChars) != -1) writer.WriteString(String.Format(@"<![CDATA[{0}]]>", pi.GetValue(this, null).ToString()));
else writer.WriteString(pi.GetValue(this, null).ToString());
和
if (val.IndexOfAny(invalidChars) != -1) writer.WriteRaw(String.Format(@"<![CDATA[{0}]]>", pi.GetValue(this, null).ToString()));
else writer.WriteString(pi.GetValue(this, null).ToString());
然后 CDATA 被正确地写入流并以正确的格式保存到磁盘。
WriteString 已替换为 WriteRaw。
我有一个自定义 XML 序列化器,如下所示
public void WriteXml(XmlWriter writer)
{
foreach (PropertyInfo pi in this.GetType().GetProperties())
{
if (pi.GetCustomAttributes(typeof(XmlIgnoreAttribute), true).Count() == 0)
{
var attrList = pi.GetCustomAttributes(typeof(XmlElementAttribute), true);
if (attrList.Count() > 0)
{
XmlElementAttribute xe = (XmlElementAttribute)attrList[0];
writer.WriteStartElement(xe.ElementName);
}
else
{
writer.WriteStartElement(pi.Name);
}
if (pi.PropertyType == typeof(int) || (pi.PropertyType == typeof(float)))
{
writer.WriteString(pi.GetValue(this, null).ToString());
}
else if (pi.PropertyType == typeof(DateTime))
{
DateTime dt = (DateTime)(pi.GetValue(this, null));
writer.WriteString(dt.ToString("yyyyMMddHHmm"));
}
else
{
if (pi.GetValue(this, null) == null) writer.WriteString(String.Empty);
else
{
// write code to generate CDATA
String val = pi.GetValue(this, null).ToString();
if (val.IndexOfAny(invalidChars) != -1)
writer.WriteString(String.Format(@"<![CDATA[{0}]]>", pi.GetValue(this, null).ToString()));
else writer.WriteString(pi.GetValue(this, null).ToString());
}
}
writer.WriteEndElement();
}
}
}
}
}
当值包含在 XML 值中无效的字符之一时,就会出现问题。使用这些行已成功检测到
if (val.IndexOfAny(invalidChars) != -1)
writer.WriteString(String.Format(@"<![CDATA[{0}]]>", pi.GetValue(this, null).ToString()));
else writer.WriteString(pi.GetValue(this, null).ToString());
问题是 CDATA 的创建——我得到的不是格式正确的 CDATA,而是 > > ;和 < ;
那么您应该如何在自定义序列化程序中创建格式正确的 CDATA?
Jeroen Mostert 在评论中提供的答案。
替换以下代码
if (val.IndexOfAny(invalidChars) != -1) writer.WriteString(String.Format(@"<![CDATA[{0}]]>", pi.GetValue(this, null).ToString()));
else writer.WriteString(pi.GetValue(this, null).ToString());
和
if (val.IndexOfAny(invalidChars) != -1) writer.WriteRaw(String.Format(@"<![CDATA[{0}]]>", pi.GetValue(this, null).ToString()));
else writer.WriteString(pi.GetValue(this, null).ToString());
然后 CDATA 被正确地写入流并以正确的格式保存到磁盘。
WriteString 已替换为 WriteRaw。