2

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

XML 数据源:

  • 可能包含需要删除的无效十六进制字符。
  • 可能包含与文档声明的编码不匹配的字符。

例如,云中的某些 XML 数据源将声明编码为utf-8,但实际编码为windows-1252ISO 8859-1,这可能会导致在创建 XmlReader 时抛出无效字符异常流。

来自StreamReader.CurrentEncoding属性文档:“当前阅读器使用的当前字符编码。在第一次调用 StreamReader 的任何 Read 方法后,该值可能不同,因为在第一次调用 Read 方法之前不会进行编码自动检测。 " 这似乎表明可以在第一次读取后检查 CurrentEncoding,但是当我们需要将 XML 数据写入 Stream 时,我们是否会卡住存储此编码?

我希望找到一种最佳实践,针对 XML 数据源安全地创建 XPathNavigator/IXPathNavigable 实例,该数据源将优雅地处理编码无效字符问题(最好在 C# 中)。

4

3 回答 3

2

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

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

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

编辑:

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

于 2009-01-28T04:53:54.410 回答
1

可以使用DecoderFallback类(和一些相关的类)来处理坏字符,要么跳过它们,要么做其他事情(用新的编码重新开始?)。

于 2009-01-28T03:12:47.110 回答
0

当使用 XmlTextReader 或类似的东西时,阅读器本身会找出 xml 文件中声明的编码。

于 2008-10-31T23:03:44.630 回答