XmlDocument.Load()方法无法解码€(欧元)

22 浏览
0 Comments

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,而实际上文件是存在的。

出了什么问题?

0
0 Comments

XmlDocument.Load()方法无法解码€(欧元)的原因是XML定义的编码方式不正确。解决方法是将内容放在CDATA元素内,并使用等效的url-encoded(或http-encoded)值转义所有特殊字符。

最好将代码放在代码块中,以便正确显示。CDATA部分对解码问题没有帮助,事实上,由于它们只包含原始字符数据,它们会阻止您使用字符引用(如€)。第二点(2)没有具体修复问题,但是目的是保护更多特殊字符(如果它们存在于值中)。第三点(3)中我故意使用了url编码格式的示例%3E(而不是€),这应该在从xml中提取值后进行解码。

0
0 Comments

问题的原因是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编码转换为正确的编码,或者使用其他方法加载和处理文件。

0
0 Comments

问题的原因是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头部的编码声明,这个实现方式是合理的。

0