XML反序列化特殊字符

时间:2016-10-05 13:47:13

标签: c# xml serialization

我想反序列化一个xml文件,该文件在其中一个字段中有一个特殊字符。该字符为十六进制0x05,并导致xml文件为。 我能够序列化对象,但不能再次反序列化它。 我经常使用这种技术,但这是第一次不起作用。 这是问题的最小例子:

using System.Xml.Serialization;
using System.IO;

namespace XMLTest
{
    class Program
    {
        static void Main(string[] args)
        {
            SpecialCharacter testobject = new SpecialCharacter();
            string filename = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + @"\testfile.xml";

            //serialize
            StreamWriter writer = System.IO.File.CreateText(filename);
            XmlSerializer xmlserialize = new XmlSerializer(typeof(SpecialCharacter));
            xmlserialize.Serialize(writer, testobject);
            writer.Flush();
            writer.Close();

            //deserialize
            StreamReader reader = File.OpenText(filename);
            XmlSerializer xmldeserialize = new XmlSerializer(typeof(SpecialCharacter));
            testobject = (SpecialCharacter)xmldeserialize.Deserialize(reader);
            reader.Close();
        }
    }

    public class SpecialCharacter
    {
        public string special = char.ConvertFromUtf32(0x05).ToString();
    }
}

2 个答案:

答案 0 :(得分:2)

您必须使用将Normalization属性设置为false的特殊阅读器。

所以而不是

StreamReader reader = File.OpenText(filename);

使用

XmlTextReader reader = new XmlTextReader(filename);

现在应该可以了。

答案 1 :(得分:1)

这里有两个简单的( - )解决方案:

  • 使用XmlTextReader.Create代替File.CreateText并添加new XmlReaderSettings() { CheckCharacters = false }作为第二个参数。不过,你应该避免这样说,除非你只是处理你自己创建的文件并知道它们的内容。
  • 在Base64中序列化String
public class SpecialCharacter
{
    [XmlElement(ElementName = "special")]
    public String Base64
    {
        get
        {
            return Convert.ToBase64String(System.Text.Encoding.UTF32.GetBytes(special));
        }
        set
        {
            if (value == null)
            {
                special = null;
                return;
            }

            special = System.Text.Encoding.UTF32.GetString(Convert.FromBase64String(value));
        }
    }

    [XmlIgnore]
    public String special = Char.ConvertFromUtf32(0x05).ToString();
}