Hexadecimal value 0x00 is a invalid character
我从StringBuilder生成XML文档,基本上是这样的:
1 | string.Format("<text><row>{0}</row><col>{1}</col><textHeight>{2}</textHeight><textWidth>{3}</textWidth><data>{4}</data><rotation>{5}</rotation></text> |
后来,类似:
1 2 3 4 5 6 7 | XmlDocument document = new XmlDocument(); document.LoadXml(xml); XmlNodeList labelSetNodes = document.GetElementsByTagName("labels"); for (int index = 0; index < labelSetNodes.Count; index++) { //do something } |
所有数据都来自数据库。
最近,我遇到了一些有关该错误的问题:
Hexadecimal value 0x00 is a invalid character, line 1, position nnnnn
但是它并不一致。
有时某些"空白"数据会起作用。
"故障"数据在某些PC上有效,但在其他PC上则不可用。
在数据库中,数据始终为空字符串。 永远不会为空
并在XML文件中以
sql server的版本(2008失败,2005可以工作)和排序规则也可能存在差异。
不确定是否有任何可能的原因?
但是完全相同的代码和数据有时会失败。 任何想法出在哪里?
没有您的实际数据或来源,我们将很难诊断出问题所在。但是,我可以提出一些建议:
- Unicode NUL(0x00)在所有版本的XML中都是非法的,并且验证解析器必须拒绝包含它的输入。
- 尽管有上述情况;真实世界中未经验证的XML可以包含可以想象的任何形式的乱码。
- XML 1.1允许使用零宽度和非打印控制字符(NUL除外),因此您无法在文本编辑器中查看XML 1.1文件并告诉其包含哪些字符。
鉴于您所写的内容,我怀疑将数据库数据转换为XML的方法是否已损坏;它正在传播非XML字符。
使用非XML字符(NUL,DEL,控制字符等)创建一些数据库条目,然后在其上运行XML转换器。将XML输出到文件,然后在十六进制编辑器中查看它。如果其中包含非XML字符,则您的转换器已损坏。对其进行修复,或者,如果不能,则创建一个预处理器以拒绝带有此类字符的输出。
如果转换器输出看起来不错,则问题出在您的XML使用方中;它在某处插入非XML字符。您将必须将消耗过程分为几个步骤,检查每个步骤的输出,并缩小引入不良字符的范围。
检查文件编码(用于UTF-16)
更新:我自己碰到了一个例子!发生的事情是,生产者将XML编码为UTF16,而消费者则期望UTF8。由于UTF16将0x00用作所有ASCII字符的高字节,而UTF8则不使用,因此使用者将第二个字节视为NUL。就我而言,我可以更改编码,但是建议所有XML有效负载均以BOM表开头。
就我而言,这需要花一些时间才能找到。
我的背景
我正在使用Elmah从网站查看异常/错误日志。 Elmah在异常发生时以大XML文档的形式返回服务器的状态。对于我们的报告引擎,我使用XmlWriter漂亮地打印了XML。
在网站攻击期间,我注意到某些xml文件没有解析,并且正在接收此
NON-RESOLUTION:我将文档转换为
当我扫描xml文档时,发现以下内容:
1 2 3 4 5 6 7 8 | ... <form> ... <item name="SomeField"> <value string="C:\\boot.ini .htm" /> </item> ... |
有一个nul字节编码为html实体
解决方案:为了解决编码问题,我在将
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | XmlDocument xml = new XmlDocument(); details.Xml = details.Xml.Replace("","[0x00]"); // in my case I want to see it, otherwise just replace with"" xml.LoadXml(details.Xml); string formattedXml = null; // I have this in a helper function, but for this example I have put it in-line StringBuilder sb = new StringBuilder(); XmlWriterSettings settings = new XmlWriterSettings { OmitXmlDeclaration = true, Indent = true, IndentChars ="\\t", NewLineHandling = NewLineHandling.None, }; using (XmlWriter writer = XmlWriter.Create(sb, settings)) { xml.Save(writer); formattedXml = sb.ToString(); } |
经验教训:如果传入的数据在输入时是html编码的,则使用关联的html实体清除非法字节。
为了补充上面的Sonz回答,以下对我们有用。
1 2 3 4 | //Instead of XmlString.Replace("","[0x00]"); // use this XmlString.Replace("\\x00","[0x00]"); |
当我在Web.config文件中保存一些unicode数据(印地语)并使用" Unicode"编码保存时,在ASP.NET应用程序中也会遇到相同的错误。
当我使用" UTF-8"编码保存Web.config文件时,它为我解决了该错误。
作为一个较晚的答案:
上传报告时,SSRS ReportService2005.asmx存在此问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | Public Shared Sub CreateReport(ByVal strFileNameAndPath As String, ByVal strReportName As String, ByVal strReportingPath As String, Optional ByVal bOverwrite As Boolean = True) Dim rs As SSRS_2005_Administration_WithFOA = New SSRS_2005_Administration_WithFOA rs.Credentials = ReportingServiceInterface.GetMyCredentials(strCredentialsURL) rs.Timeout = ReportingServiceInterface.iTimeout rs.Url = ReportingServiceInterface.strReportingServiceURL rs.UnsafeAuthenticatedConnectionSharing = True Dim btBuffer As Byte() = Nothing Dim rsWarnings As Warning() = Nothing Try Dim fstrStream As System.IO.FileStream = System.IO.File.OpenRead(strFileNameAndPath) btBuffer = New Byte(fstrStream.Length - 1) {} fstrStream.Read(btBuffer, 0, CInt(fstrStream.Length)) fstrStream.Close() Catch ex As System.IO.IOException Throw New Exception(ex.Message) End Try Try rsWarnings = rs.CreateReport(strReportName, strReportingPath, bOverwrite, btBuffer, Nothing) If Not (rsWarnings Is Nothing) Then Dim warning As Warning For Each warning In rsWarnings Log(warning.Message) Next warning Else Log("Report: {0} created successfully with no warnings", strReportName) End If Catch ex As System.Web.Services.Protocols.SoapException Log(ex.Detail.InnerXml.ToString()) Catch ex As Exception Log("Error at creating report. Invalid server name/timeout?" + vbCrLf + vbCrLf +"Error Description:" + vbCrLf + ex.Message) Console.ReadKey() System.Environment.Exit(1) End Try End Sub ' End Function CreateThisReport |
当您分配一个比RDL(XML)文件大至少1个字节的字节数组时,会发生此问题。
具体来说,我使用了C#到vb.net转换器,
1 | btBuffer = new byte[fstrStream.Length]; |
进入
1 | btBuffer = New Byte(fstrStream.Length) {} |
但是因为在C#中,数字表示数组中的元素数,而在VB.NET中,该数字表示数组的上限,所以我有一个多余的字节,从而导致此错误。
因此,问题的解决方案很简单:
1 | btBuffer = New Byte(fstrStream.Length - 1) {} |
我在这里使用IronPython(与.NET API相同),并以UTF-8格式读取文件,以便正确处理BOM表为我解决了该问题:
1 2 | xmlFile = Path.Combine(directory_str, 'file.xml') doc = XPathDocument(XmlTextReader(StreamReader(xmlFile.ToString(), Encoding.UTF8))) |
1 2 | doc = XmlDocument() doc.Load(XmlTextReader(StreamReader(xmlFile.ToString(), Encoding.UTF8))) |