如何针对C#中的流安全地创建XPathNavigator?

如何针对C#中的流安全地创建XPathNavigator?,c#,xml,encoding,stream,C#,Xml,Encoding,Stream,给定一个流作为输入,如何针对XML数据源安全地创建XPathNavigator XML数据源: 可能包含需要删除的无效十六进制字符 可能包含与文档的声明编码不匹配的字符 例如,云中的一些XML数据源的声明编码为utf-8,但实际编码为windows-1252或ISO 8859-1,这可能导致在针对流创建XmlReader时引发无效字符异常 来自StreamReader.CurrentEncoding属性文档:“当前读取器使用的当前字符编码。在首次调用StreamReader的任何读取方法后,

给定一个流作为输入,如何针对XML数据源安全地创建XPathNavigator

XML数据源:

  • 可能包含需要删除的无效十六进制字符
  • 可能包含与文档的声明编码不匹配的字符
例如,云中的一些XML数据源的声明编码为utf-8,但实际编码为windows-1252或ISO 8859-1,这可能导致在针对流创建XmlReader时引发无效字符异常

来自StreamReader.CurrentEncoding属性文档:“当前读取器使用的当前字符编码。在首次调用StreamReader的任何读取方法后,该值可能会有所不同,因为编码自动检测只有在第一次调用读取方法后才会完成。”这似乎表明在第一次读取之后可以检查CurrentEncoding,但是当我们需要将XML数据写入流时,我们是否仍在存储此编码


我希望找到一种最佳实践,可以针对XML数据源安全地创建XPathNavigator/IXPathNavigatable实例,该实例将优雅地处理编码无效字符的问题(最好使用C语言)。

当使用XmlTextReader或类似工具时,读取器本身将找出xml文件中声明的编码。

可以使用该类(以及一些相关类)来处理错误字符,方法是跳过这些字符或执行其他操作(使用新编码重新启动?).

当一些XML片段使用错误的编码导入CRM系统时,我遇到了类似的问题(没有与XML片段一起存储编码)

在一个循环中,我使用列表中的当前编码创建了一个包装流。编码是使用DecoderExceptionFallback和EncoderExceptionFallback选项构建的(如@Doug所述)。如果在处理过程中引发DecoderFallbackException,则会重置原始流,并使用下一个最可能的编码

我们的编码列表类似于UTF-8、Windows-1252、GB-2312和US-ASCII。如果您从列表的末尾掉了下来,那么流就非常糟糕,并且被拒绝/忽略/等等

编辑:


我快速创建了一个示例和基本测试文件(源代码)。代码没有任何启发式方法可在两个都匹配同一组字节的代码页之间进行选择,因此Windows-1252文件可能被检测为GB2312,反之亦然,具体取决于文件内容和编码首选项顺序。

StreamReader.CurrentEncoding:“当前读取器使用的当前字符编码。在第一次调用StreamReader的任何读取方法后,该值可能会有所不同,因为编码自动检测直到第一次调用读取方法才完成。“所以建议在读取后进行CurrentEncoding?我不确定这是否有效,但这似乎是一个好方法。我唯一能想到的就是推出一个定制的XML解析器。回答得好。这听起来是解决这个问题的好办法,你能提供一些示例代码吗?