2012-07-26 118 views
3

当我在某些场合中对一个字符串(即一个xml文件)进行urlEncode时,它会在文件末尾添加%00字符。我想知道为什么会发生这种情况,如果可以防止(我总是可以擦除%00字符)。 xml文件是使用xmlwriter创建的。奇怪的是我使用相同的代码来创建其他XML文件,编码后它不会添加%00个字符。UrlEncode .net在字符串末尾添加%00个字符

例子:

<?xml version="1.0" encoding="iso-8859-1"?> 
<!DOCTYPE peticion > 
<peticion> 
    <nombre>Info hotel</nombre> 
    <agencia>HOTUSA</agencia> 
    <tipo>15</tipo> 
</peticion> 

编辑:创建XML这是我做的。

Dim xmlWriterSettings As New System.Xml.XmlWriterSettings 
     With xmlWriterSettings 
      .Encoding = Encoding.GetEncoding("iso-8859-1") 
      .OmitXmlDeclaration = False 
      .Indent = True 
     End With 

     Dim ms As New IO.MemoryStream 

     Using writer As System.Xml.XmlWriter = System.Xml.XmlWriter.Create(ms, xmlWriterSettings) 
      With writer 
       .WriteDocType("peticion", Nothing, Nothing, Nothing) 
       .WriteStartElement("peticion") 
       .WriteElementString("nombre", "Info hotel") 
       .WriteElementString("agencia", "HOTUSA") 
       .WriteElementString("tipo", "15") 
       .WriteEndElement() 
      End With 
     End Using 

     Dim xml As String = Encoding.GetEncoding("iso-8859-1").GetString(ms.GetBuffer) 

Dim XmlEncoded As String = HttpUtility.UrlEncode(xml) 

XmlEncoded包含:

%3c%3fxml+version%3d%221.0%22+encoding%3d%22iso-8859-1%22%3f%3e%0d%0a%3c!DOCTYPE+peticion+%3e%0d% 
0a%3cpeticion%3e%0d%0a++%3cnombre%3eInfo+hotel%3c%2fnombre%3e%0d%0a++%3cagencia%3eHOTUSA%3c% 
2fagencia%3e%0d%0a++%3ctipo%3e15%3c%2ftipo%3e%0d%0a%3c%2fpeticion%3e%00%00%00%00%00%00%00%00%00% 
00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00% 
00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00% 
00%00%00%00%00%00%00%00%00%00%00%00%00%00 

,所有这些%00从何而来?

+0

请出示变量'XML的声明'和创建其内容的代码。 – Codo 2012-07-26 15:04:38

回答

4

MemoryStream.GetBuffer的言论提供相应的指导:

注意,缓冲区包含分配的字节,这可能是未使用的。例如,如果将字符串“test”写入到MemoryStream对象中,则从GetBuffer返回的缓冲区的长度为256,而不是4,未使用252个字节。要仅获取缓冲区中的数据,请使用ToArray方法;但是,ToArray会在内存中创建数据的副本。

修改代码如下所示:

Dim xml As String = Encoding.GetEncoding("iso-8859-1").GetString(ms.ToArray) 

事实上,在这种情况下,更好的选择是使用StringBuilder

Dim sb As New StringBuilder 
Using writer As XmlWriter = XmlWriter.Create(sb, xmlWriterSettings) 
    ' ... 
End Using   

Dim xml as String = sb.ToString() 
+0

我更喜欢你的'StringBuilder'答案。但是,我很苦,所以没有upvote。 :) – Sumo 2012-07-26 16:31:30

+0

测试这两个解决方案,他们工作!谢谢。 – ShengLong 2012-07-27 14:40:33

1

我相信ms.GetBuffer包含比你想象的更多。 %00表示NULL,我的猜测是缓冲区末尾包含填充NULL。

而是做:

Using ms As New IO.MemoryStream 
    Dim writer As System.Xml.XmlWriter = System.Xml.XmlWriter.Create(ms, xmlWriterSettings) 

    With writer 
     .WriteDocType("peticion", Nothing, Nothing, Nothing) 
     .WriteStartElement("peticion") 
     .WriteElementString("nombre", "Info hotel") 
     .WriteElementString("agencia", "HOTUSA") 
     .WriteElementString("tipo", "15") 
     .WriteEndElement() 
    End With 

    ms.Position = 0 
    Dim xml As String = ms.ReadToEnd() 
    Dim XmlEncoded As String = HttpUtility.UrlEncode(xml) 
End Using 

有关从MemoryStream得到一个字符串的详细信息,请参阅this question

请参阅this documentation详细说明缓冲区包含可能未使用的分配字节这一事实。

+0

我认为@sumo是正确的。 MemoryStream的文档解释说MemoryStreams不一定可以调整大小,所以可能会有填充:“使用无符号字节数组创建的内存流提供了不可调整大小的数据流。使用字节数组时,既不能附加到也不会缩小流,尽管您可能可以根据传入构造函数的参数修改现有内容。空的内存流可调整大小,并且可以写入和读取。“ – 2012-07-26 15:54:24

+0

感谢您的回答,相扑。您首先指出ms.GetBuffer中存在一些奇怪的东西。 – ShengLong 2012-07-27 14:52:53

相关问题