【问题标题】:How do I safely create an XPathNavigator against a Stream in C#?如何在 C# 中针对流安全地创建 XPathNavigator?
【发布时间】:2010-09-20 06:56:20
【问题描述】:

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

XML 数据源:

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

例如,云中的一些XML数据源会声明编码为utf-8,但实际编码为windows-1252 ISO 8859-1,这会导致在针对 Stream 创建 XmlReader 时引发无效字符异常。

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

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

【问题讨论】:

    标签: c# xml encoding stream


    【解决方案1】:

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

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

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

    编辑:

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

    【讨论】:

    • 这听起来是一个很好的解决方案,你能提供一些示例代码吗?
    【解决方案2】:

    可以使用DecoderFallback 类(和一些相关的类)来处理坏字符,方法是跳过它们或执行其他操作(使用新编码重新开始?)。

    【讨论】:

    • 我不确定这是否可行,但这似乎是一个好方法。我唯一能想到的就是滚动自定义 XML 解析器。很好的答案。
    【解决方案3】:

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

    【讨论】:

    • StreamReader.CurrentEncoding: "当前阅读器使用的当前字符编码。第一次调用 StreamReader 的任何 Read 方法后,值可以不同,因为编码自动检测直到第一次调用一种读取方法。”那么推荐读后CurrentEncoding?
    猜你喜欢
    • 1970-01-01
    • 2021-03-18
    • 1970-01-01
    • 2012-03-08
    • 1970-01-01
    • 1970-01-01
    • 2015-05-13
    相关资源
    最近更新 更多