XDocument.Load(Stream)如何检测XML消息的结束?

时间:2014-08-20 13:06:06

标签: c# xml linq-to-xml

我正在从TcpClient流中读取XDocument。在实施时,我想知道 XDocument.Load(Stream)如何知道文档何时完成?

我想到了几个想法,比如收到的流结束或没有更多的字节可用。但现在看起来更多的是当收到EndElement时Load()完成。

有人知道Load(Stream)内部是如何工作的吗?

由于 汤姆

3 个答案:

答案 0 :(得分:2)

很容易证明它读取了结束元素 - 您只需创建一个包含end元素后面的数据的XML文件,使其无效:

<root>
  <child />
</root>

More stuff

如果你加载它,你会得到这样的例外:

Unhandled Exception: System.Xml.XmlException: Data at the root level is invalid.
Line 5, position 1.

我强烈希望它能读到流的末尾。

答案 1 :(得分:1)

取自反编译程序集:

[__DynamicallyInvokable]
    [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
    public static XDocument Load(Stream stream)
    {
      return XDocument.Load(stream, LoadOptions.None);
    }

    [__DynamicallyInvokable]
    public static XDocument Load(Stream stream, LoadOptions options)
    {
      XmlReaderSettings xmlReaderSettings = XNode.GetXmlReaderSettings(options);
      using (XmlReader reader = XmlReader.Create(stream, xmlReaderSettings))
        return XDocument.Load(reader, options);
    }

在内部创建一个XML Reader并调用XDocument.Load Method (XmlReader) XML读取器是由Stream创建的,通过将其读取到最后(通过遵循实现)

答案 2 :(得分:1)

已更新:我将XDocument误读为XmlDocument。答案仍然有效。您读取直到流的结尾,因为XDocument和XmlDocument都链接到XmlTextReaderImpl.InitStreamInput,这是流读取发生的地方。到达流的末尾后,即可开始处理数据。如果解析失败,您将获得XmlException,但这会在所有流读取完成后发生。

如果您浏览 .NET Reference Source ,您会看到以下内容(从流中读取):

XDocument.Load(Stream),调用XmlReader.Create,它实例化XmlReaderSettings并在该实例上调用CreateReader,该实例实例化XmlTextReaderImpl,该实例调用该实例上的FinishInitStream,调用InitStreamInput。这是大部分工作发生的地方,您可以在哪里找到基于读取的字符数的文件结尾检查。

注意:XmlDocument.Load(Stream)遵循调用InitStreamInput的类似方法(因此使用相同的流读取代码)