XmlDocument.Load()方法无法解码€(欧元)
XmlDocument.Load()方法无法解码€(欧元)
我有一个以Iso-latin-15(也称为Iso-Latin-9)编码的XML文档file.xml
。
€.txt
通过我喜欢的文本编辑器,我可以确定这个文件以Iso-Latin-15编码(不是UTF-8)。
我的软件是用C#编写的,想要提取元素f
。
XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load("file.xml");
在实际应用中,我有一个XMLResolver来设置凭据。但基本上,我的代码就是这么简单。加载过程很顺利,没有出现任何异常。
现在,当我提取值时出现了问题:
//xnsm是XmlNameSpace管理器 XmlNode n = xmlDoc.SelectSingleNode("//root/f", xnsm); if (n != null) String filename = n.InnerText;
Visual Studio调试器显示的filename = □.txt
这可能只是Visual Studio的一个bug。不幸的是,File.Exists(filename)
返回false,而实际上文件是存在的。
出了什么问题?
问题的原因是XmlDocument.Load()方法无法正确解码欧元符号(€)。根据字符串内容的实际Unicode码点而不是当前字体可以显示的内容来显示字符串的内容,可以解决这个问题。使用foreach循环遍历字符串中的每个字符,然后使用Console.WriteLine()方法显示每个字符和它的十六进制Unicode码点。通过查找Unicode码表,可以确定问题字符的真实内容。在这个例子中,问题字符的Unicode码点是:0080,它是Unicode中的一个控制字符,而在Windows-CP1252编码中,它是欧元符号。这个情况下,可以怀疑XmlDocument实现中存在一个错误。接下来,可以检查文件的字节内容以及.NET是否支持iso-8859-15编码。推测文件实际上是使用windows-1252编码而不是ISO-8859-15编码。最后,可以确定输入文件中确实包含了0x80字节,而不是预期的0xA4字节。解决方法是将文件内容从windows-1252编码转换为正确的编码,或者使用其他方法加载和处理文件。
问题的原因是XmlDocument.Load()
方法默认使用UTF-8编码,不管XML的实际编码是什么。解决方法是创建一个带有正确编码的StreamReader
对象,并将其作为参数传递给Load()
方法。
具体的解决方法是:
xmlDoc.Load(new StreamReader( File.Open("file.xml"), Encoding.GetEncoding("iso-8859-15")));
另外,微软的文档中提到,XML声明中的编码声明只是指定了XML文档的编码格式,并不修改或控制数据的实际编码格式。因此,不能假设输入文件的编码是Iso-8859-15。
总之,Load()
方法会注意XML头部的编码声明,这个实现方式是合理的。