C#XmlWriter和无效的UTF8字符

时间:2010-12-08 22:51:13

标签: c# .net xml utf-8

我们创建了一个单元测试,它使用以下方法生成随机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已经逃脱了&amp;,&lt;,&gt;等等,我们如何处理其他无效字符,如控制字符等?

PS - 让我知道我们的UTF8发生器是否有缺陷(我已经看到我不应该让它产生'\ 0')

4 个答案:

答案 0 :(得分:7)

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

答案 1 :(得分:6)

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

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

答案 2 :(得分:5)

有两个问题:

  1. 并非所有字符都对XML有效,甚至是转义。对于XML 1.0,Unicode代码点值小于0x0020且有效的唯一字符是TAB&#9;),LF&#10;)和{{1 (CR)。请参阅XML 1.0, Section 2.2, Characters

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

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

答案 3 :(得分:2)

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

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

更新:如果要对XML中的任意二进制数据进行编码,请在将其写入XML之前使用Base64或其他编码。