2010-12-08 116 views
5

我们创建了一个使用下面的方法来生成随机UTF8文本单元测试:C#的XmlWriter和无效的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”)

回答

7

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

+0

我想我可以在我的随机字节发生器上检查IsXmlChar,并在失败时重试。我认为这是一个很好的解决方案。我们并不担心性能,因为这是单元测试。 – jonathanpeppers 2010-12-09 13:16:04

6

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

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

+3

得到了一个代码示例? – jonathanpeppers 2010-12-08 23:09:06

2

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

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

更新:如果您想要用XML编码任意的二进制数据,那么在将它们写入XML之前,先使用Base64或其他编码。

5

有两个问题:

  1. 并不是所有的字符都是有效的XML,甚至逃跑。对于XML 1.0,Unicode码值小于0x0020的唯一有效字符是TAB&#9;),LF&#10;)和CR&#13;)。见XML 1.0, Section 2.2, Characters

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

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