【问题标题】:Custom XML Serialization and handling CDATA自定义 XML 序列化和处理 CDATA
【发布时间】:2018-11-12 14:27:56
【问题描述】:

我有一个自定义的 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 的创建 - 我得到的是 & gt; 而不是正确格式化的 CDATA <

那么您应该如何在自定义序列化程序中创建格式正确的 CDATA?

【问题讨论】:

  • 如果你想直接写标记,使用WriteRaw而不是WriteString。 (请注意,在更广泛的背景下,我不知道以这种方式编写 CDATA 是否是最好的方法——我的意思是,毕竟还有 WriteCData。)
  • 谢谢 - 成功了

标签: c# xml cdata serialization


【解决方案1】:

Jeroen Mostert 在 cmets 中提供的答案。

替换以下代码

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。

【讨论】:

  • 出于好奇,writer.WriteCData(pi.GetValue(this, null).ToString()) 也有效吗?它应该,而且会更简单。此外,从技术上讲,如果 everything 都写为 CDATA,您的输出不会出错,因此您可以省略检查 - 但它可能比必要的要大。
  • Jeroen Mostert 老实说我不确定。我正在处理医疗记录,所以选择了你的原始答案,因为我需要让它很快工作。出于同样的原因,我想减少在处理过程中对数据所做的更改次数。出现问题的原因是数据源生成的 XML 没有读取数据的应用程序那么严格。
猜你喜欢
  • 2012-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-31
  • 2015-01-31
  • 2013-11-03
  • 1970-01-01
相关资源
最近更新 更多