4

我需要逐步处理从ResponseStream异步回调 XML 加载的内容。

回复有:

  <root>
     <node ...>
        .....
     </node>
     <node />
     ...
  </root>

架构,我需要<node>在他们完成之前有能力过程。

有没有使用标准 .NET 解析它的正常方法?

4

3 回答 3

3
System.Xml.XmlTextReader 

“表示提供对 XML 数据的快速、非缓存、只进访问的阅读器。”

http://msdn.microsoft.com/en-us/library/system.xml.xmltextreader.aspx

编辑:这是一个快速破解,但它确实表明读者实际上是懒惰的。

 public class XmlTextReaderTest
    {
        public void RunTest()
        {
            var fs = new XmlTextReader(new Fs(@"c:\TestXml.xml"));
            while (fs.Read())
                File.AppendAllText(@"c:\xLog.txt", "Processing node..." + Environment.NewLine);
        }
    }

    public class Fs : FileStream
    {
        public Fs(string path)
            : base(path, FileMode.Open)
        {

        }

        public override int Read(byte[] array, int offset, int count)
        {
            File.AppendAllText(@"c:\xLog.txt", "Reading from stream..." + Environment.NewLine);
            var ans = base.Read(array, offset, count);
            return ans;
        }
}
于 2010-08-08T08:00:18.107 回答
1

不要在异步回调上调用它,你不需要(相信我,这会变得更清楚......)。

ResponseStream 将在信息可用时加载。对于未分块发送的小流(恐怕对于“小”值相当大),这将是在整个流已被下载时。但是,如果流是使用分块传输编码发送的(如果缓冲被关闭或Response.Flush()调用,则在 ASP.NET 中会发生这种情况,其他 Web 服务器技术具有它们的等价物),那么流将在第一个块处可用。

当 GetResponse() 返回时,从 ResponseStream 创建您的 XMLReader。它将从可用的第一个块开始处理,并在后续块以对您的代码非常透明的方式到达时获取后续块。

确保您在可用的基础上处理这些节点实际上使代码进一步受益。例如,如果您要输出到控制台或表单,请在处理每个节点(或一小批节点)时执行此操作,而如果您从这些节点创建对象,则使用yield return它们而不是建立一个集合。

现在,这里的重要问题显然是网络流是否被分块,而不是您的处理代码。如果生产者是无法说服的另一方,那么您将需要在处理过程中降低到较低的水平。但是,如果是这种情况,那么这样做很可能是错误的优化,因为整个处理将在他们发送第一个字节之前完成,这是最大的延迟。确实,如果下载整个响应的延迟对您的代码来说是个问题,那么您需要它们开始发送分块,因为即使您采用最有效的方法,延迟仍然太大。

作为记录,我最近证实,在处理分块数据的 WebResponse 上使用 XmlReader(我控制客户端和服务器代码,并且可以在调试器中运行并检查操作顺序) ),处理确实在每个块可用时完成。

于 2010-08-08T12:50:31.090 回答
0

是的,您可以使用一个阅读器。基本上沿着流并为它标识的每个元素(元素、属性等)抛出 n 事件。

于 2010-08-08T07:50:28.410 回答