简体   繁体   中英

Custom XML Serialization and handling CDATA

I have a custom XML Serializer as follows

    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();
            }


        }
    }
}

}

The problem arises when the value contains one of the characters which is invalid in an XML Value. This is detected successfully with these lines

                    if (val.IndexOfAny(invalidChars) != -1)
                        writer.WriteString(String.Format(@"<![CDATA[{0}]]>", pi.GetValue(this, null).ToString()));
                    else writer.WriteString(pi.GetValue(this, null).ToString());

The problem is the creation of the CDATA - instead of getting a properly formatted CDATA what I am getting is & gt ; and & lt ;

So how should you create a properly formatted CDATA within a custom serializer?

Answer provided by Jeroen Mostert in the comments.

Replace the following code

if (val.IndexOfAny(invalidChars) != -1) writer.WriteString(String.Format(@"<![CDATA[{0}]]>", pi.GetValue(this, null).ToString()));
else writer.WriteString(pi.GetValue(this, null).ToString());

with

if (val.IndexOfAny(invalidChars) != -1) writer.WriteRaw(String.Format(@"<![CDATA[{0}]]>", pi.GetValue(this, null).ToString()));
else writer.WriteString(pi.GetValue(this, null).ToString());

The CDATA is then written to the stream correctly and saved to disk in the correct format.

WriteString has been replaced with WriteRaw.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM