【问题标题】:C# XmlWriter and invalid UTF8 charactersC# XmlWriter 和无效的 UTF8 字符
【发布时间】:2011-05-22 13:05:34
【问题描述】:

我们创建了一个单元测试,它使用以下方法生成随机 UTF8 文本:

        private static Random _rand = new Random(Environment.TickCount);

        public static byte CreateByte()
        {
            return (byte)_rand.Next(byte.MinValue, byte.MaxValue + 1);
        }

        public static byte[] CreateByteArray(int length)
        {
            return Repeat(CreateByte, length).ToArray();
        }

        public static string CreateUtf8String(int length)
        {
            return Encoding.UTF8.GetString(CreateByteArray(length));
        }

        private static IEnumerable<T> Repeat<T>(Func<T> func, int count)
        {
            for (int i = 0; i < count; i++)
            {
                yield return func();
            }
        }

在向我们的业务逻辑发送随机 UTF8 字符串时,XmlWriter 会写入生成的字符串,并且可能会因错误而失败:

Test method UnitTest.Utf8 threw exception: 
System.ArgumentException: ' ', hexadecimal value 0x0E, is an invalid character.

System.Xml.XmlUtf8RawTextWriter.InvalidXmlChar(Int32 ch, Byte* pDst, Boolean entitize)
System.Xml.XmlUtf8RawTextWriter.WriteAttributeTextBlock(Char* pSrc, Char* pSrcEnd)
System.Xml.XmlUtf8RawTextWriter.WriteString(String text)
System.Xml.XmlUtf8RawTextWriterIndent.WriteString(String text)
System.Xml.XmlWellFormedWriter.WriteString(String text)
System.Xml.XmlWriter.WriteAttributeString(String localName, String value)

我们希望支持传入任何可能的字符串,并且需要以某种方式转义这些无效字符。

XmlWriter已经转义了&、等,其他无效字符如控制字符等如何处理?

PS - 如果我们的 UTF8 生成器有缺陷,请告诉我(我已经看到不应该让它生成 '\0')

【问题讨论】:

    标签: c# .net xml utf-8


    【解决方案1】:

    XmlConvert Class 有很多有用的方法(如 EncodeName、IsXmlChar、...),可确保您构建有效的 Xml。

    【讨论】:

    • 我想我可以在我的随机字节生成器上检查 IsXmlChar,如果失败则重试。我认为这是一个很好的解决方案。我们不太担心性能,因为这是单元测试。
    • 在测试套件中使用随机字符时,可能很难重新创建失败的测试,因为您的测试是不确定的。
    • 这就是我们查看失败测试的调试输出的原因。我们的调试输出非常广泛。我们只是接受失败的输入并对该输入进行特定的测试。
    【解决方案2】:

    您的 UTF-8 生成器似乎有缺陷。有许多字节序列是无效的 UTF-8 编码。

    生成有效随机UTF-8编码的更好方法是生成随机字符,将它们放入字符串中,然后将字符串编码为UTF-8。

    【讨论】:

      【解决方案3】:

      有两个问题:

      1. 并非所有字符都对 XML 有效,即使是转义字符。对于 XML 1.0,唯一有效的 Unicode 代码点值小于 0x0020 的字符是 TAB (&amp;#9;)、LF (&amp;#10;) 和 CR (&amp;#13;)。见XML 1.0, Section 2.2, Characters

        对于系统支持相对较少的 XML 1.1,除NUL 之外的任何字符都可以通过这种方式进行转义。

      2. 并非所有字节序列都对 UTF-8 有效。例如,根据specification,“八位字节值 C0、C1、F5 到 FF 永远不会出现。”可能你最好只创建 Strings 个字符并忽略 UTF-8,或者创建 String,如果你真的喜欢编码,将其转换为 UTF-8 并返回。

      【讨论】:

        【解决方案4】:

        Mark 指出并非每个字节序列都是有效的 UTF-8 序列。

        我想补充一点,并不是每个字符都可以存在于 XML 文档中。只有some characters are valid,即使它们被编码为numeric character reference也是如此。

        更新:如果您想在 XML 中编码任意二进制数据,请在将它们写入 XML 之前使用 Base64 或其他一些编码。

        【讨论】:

          猜你喜欢
          • 2023-04-04
          • 2011-04-30
          • 1970-01-01
          • 2018-04-29
          • 2010-11-21
          • 1970-01-01
          • 1970-01-01
          • 2021-02-06
          • 2019-10-09
          相关资源
          最近更新 更多