【问题标题】:Why "Data at the root level is invalid. Line 1, position 1." for XML Document?为什么“根级别的数据无效。第 1 行,位置 1。”对于 XML 文档?
【发布时间】:2013-07-30 14:42:02
【问题描述】:

我正在使用第三方 DLL,它通过 Internet 传输 XML 文档。

为什么 DLL 会抛出以下异常?

根级别的数据无效。第 1 行,位置 1。(见下文 完整的异常文本。)

以下是 XML 文档的前几行:

<?xml version="1.0" encoding="utf-8"?> <REQUEST>   <HEADER>
    <REQUESTID>8a5f6d56-d56d-4b7b-b7bf-afcf89cd970d</REQUESTID>
    <MESSAGETYPE>101</MESSAGETYPE>
    <MESSAGEVERSION>3.0.2</MESSAGEVERSION>

例外:

System.ApplicationException was caught
      Message=Unexpected exception.
      Source=FooSDK
      StackTrace:
           at FooSDK.RequestProcessor.Send(String SocketServerAddress, Int32 port)
           at Foo.ExecuteRequest(Int32 messageID, IPayload payload, Provider prov)
           at Foo.SendOrder(Int32 OrderNo)
      InnerException: System.Xml.XmlException
           LineNumber=1
           LinePosition=1
           Message=Data at the root level is invalid. Line 1, position 1.
           Source=System.Xml
           SourceUri=""
           StackTrace:
                at System.Xml.XmlTextReaderImpl.Throw(Exception e)
                at System.Xml.XmlTextReaderImpl.Throw(String res, String arg)
                at System.Xml.XmlTextReaderImpl.ParseRootLevelWhitespace()
                at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
                at System.Xml.XmlTextReaderImpl.Read()
                at System.Xml.XmlLoader.Load(XmlDocument doc, XmlReader reader, Boolean preserveWhitespace)
                at System.Xml.XmlDocument.Load(XmlReader reader)
                at System.Xml.XmlDocument.LoadXml(String xml)
                at XYZ.RequestProcessor.GetObjectFromXML(String xmlResult)
                at XYZ.RequestProcessor.Send(String SocketServerAddress, Int32 port)
           InnerException:

【问题讨论】:

  • xml文件是如何通过互联网传输的? HTTP?如果是,请检查 a) 文件是否具有 BOM,并且 b) HTTP 标头还指定了非 UTF8 字符集。

标签: .net xml xmldocument xmlreader


【解决方案1】:

我最终发现存在字节标记异常并使用以下代码将其删除:

 string _byteOrderMarkUtf8 = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble());
    if (xml.StartsWith(_byteOrderMarkUtf8))
    {
        var lastIndexOfUtf8 = _byteOrderMarkUtf8.Length-1;
        xml = xml.Remove(0, lastIndexOfUtf8);
    }

【讨论】:

  • 这是零基字符数组 - 我必须使用 xml = xml.Remove(0, _byteOrderMarkUtf8.Length-1);
  • 当然应该是xml = xml.Remove(0, _byteOrderMarkUtf8.Length);,因为String.Remove(Int32, Int32) 的第二个参数是要删除的字符数,从startIndex 开始。请参阅MSDN docs
  • 为了让这段代码在 Windows Server 2012 和 Windows 7 上运行,我不得不使用if (xml.StartsWith(_byteOrderMarkUtf8, StringComparison.Ordinal))。详情请查看stackoverflow.com/a/19495964/1843329
【解决方案2】:

我可以给你两个建议:

  1. 看来您使用的是“LoadXml”而不是“Load”方法。在某些情况下,它对我有帮助。
  2. 您遇到了编码问题。你能检查XML文件的编码并写吗?

【讨论】:

  • 刚看到评论。是的,尝试将文件编码设置为 UTF8-WITHOUT-BOM
【解决方案3】:

删除&lt;?xml version="1.0" encoding="utf-8"?&gt;之前的所有内容

有时,有一些“不可见”(并非在所有文本编辑器中可见)。有些程序会添加这个。

它被称为 BOM,您可以在此处阅读更多信息:https://en.wikipedia.org/wiki/Byte_order_mark#Representations_of_byte_order_marks_by_encoding

【讨论】:

    【解决方案4】:

    如果您使用XDocument.Load(url);从另一个域获取xml,主机可能会拒绝请求并返回意外(非xml)结果,从而导致上述XmlException

    在此处查看我对这种可能性的解决方案: XDocument.Load(feedUrl) returns "Data at the root level is invalid. Line 1, position 1."

    【讨论】:

      【解决方案5】:

      此错误的主要原因是在将Streambyte[] 数组转换为.NET string 时确定编码的逻辑。

      使用 StreamReader 创建时将第二个构造函数参数 detectEncodingFromByteOrderMarks 设置为 true,将确定正确的编码并创建不会破坏 XmlDocument.LoadXml 方法的 string

      public string GetXmlString(string url)
      {
          using var stream = GetResponseStream(url);
          using var reader = new StreamReader(stream, true);
          return reader.ReadToEnd(); // no exception on `LoadXml`
      }
      

      常见的错误是在streambyte[] 上盲目地使用UTF8 编码。下面的代码会产生string,在 Visual Studio 调试器中检查或复制粘贴到某处时看起来是有效的,但如果文件的编码方式与没有 BOM 的 UTF8 不同,则与 LoadLoadXml 一起使用时会产生异常。

      public string GetXmlString(string url)
      {
          byte[] bytes = GetResponseByteArray(url);
          return System.Text.Encoding.UTF8.GetString(bytes); // potentially exception on `LoadXml`
      }
      

      因此,对于您的第三方库,他们可能使用第二种方法将 XML 流解码为 string,因此例外。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-10-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-19
        • 2011-10-28
        • 1970-01-01
        • 2018-03-30
        相关资源
        最近更新 更多