代码之家  ›  专栏  ›  技术社区  ›  Arlen Beiler

这个代码有什么问题?

  •  1
  • Arlen Beiler  · 技术社区  · 15 年前

    为什么while循环不返回任何内容?我想这和.NET有关。我有.NET 2.0。问题是,while语句将执行一次,然后退出,就像没有具有该名称的节点一样,如果确实存在的话。

    下面是XML的一个示例:

    <rss version="2.0">
        <channel>
            <title>...</title>
            <link>...</link>
            <description>...</description>
            <lastBuildDate>...</lastBuildDate>
            <item>
                <title>User greeting</title>
                <guid>...</guid>
                <link>http://...</link>
    
                <description>Voicebox number: 1</description>
                <author>Free Conference Call</author>
            </item>
            <item>
                <title>User greeting</title>
                <guid>...</guid>
                <link>http://...</link>
    
                <description>Voicebox number: 1</description>
                <author>Free Conference Call</author>
            </item>
        </channel>
    </rss>
    

    代码如下:

    HttpWebRequest webreq = (HttpWebRequest)WebRequest.Create (reqURL);
    // Set some reasonable limits on resources used by this request
    webreq.MaximumAutomaticRedirections = 4;
    webreq.MaximumResponseHeadersLength = 4;
    //====================
    // Set credentials to use for this request.
    webreq.Credentials = CredentialCache.DefaultCredentials;
    HttpWebResponse response = (HttpWebResponse)webreq.GetResponse ();
    //====================
    // Get the stream associated with the response.
    receiveStream = response.GetResponseStream ();
    //====================
    // Pipes the stream to a higher level stream reader with the required encoding format. 
    readStream = new StreamReader(receiveStream, Encoding.UTF8);
    resXML = readStream.ReadToEnd();
    readStream = new StreamReader(receiveStream, Encoding.UTF8);
    //====================
    Console.WriteLine(resXML);
    Stream XMLStream = receiveStream;
    readStream = new StreamReader(XMLStream, Encoding.UTF8);
    
    XmlReaderSettings settings = new XmlReaderSettings();
    settings.ConformanceLevel = ConformanceLevel.Fragment;
    settings.IgnoreWhitespace = true;
    settings.IgnoreComments = true;
    XmlReader reader = System.Xml.XmlReader.Create(readStream, settings);
    
    while(reader.EOF == false)
    {
        reader.ReadToFollowing("link");
        Console.WriteLine("link: " + reader.Value);
        //=======================================
        reader.ReadToFollowing("description");
        Console.WriteLine("descrip: " + reader.Value);
    }
    
    3 回复  |  直到 15 年前
        1
  •  11
  •   Jon Skeet    15 年前

    当您呼叫时,您已经从响应中读取了所有数据

    resXML = readerStream.ReadToEnd();
    

    …… readerStream readStream 都是分层的 receiveStream 因此,一旦您通过一个读取了所有数据,就不能再通过另一个读取它。

    你真的应该有一个 using 用于响应的语句——理想情况下,还包括所涉及的各种流。假设您可以创建一个 XmlReader 从一条小溪,而不仅仅是一条 StreamReader ,为什么不使用这样的东西:

    XmlReaderSettings settings = new XmlReaderSettings();
    settings.ConformanceLevel = ConformanceLevel.Fragment;
    settings.IgnoreWhitespace = true;
    settings.IgnoreComments = true;
    
    using (HttpWebResponse response = (HttpWebResponse)webreq.GetResponse())
    {
       using (Stream stream = response.GetResponseStream())
       {
           using(XmlReader reader = XmlReader.Create(stream, settings))
           {
               // Do stuff here
           }
       }
    }
    

    另外,我会 通常地 建议创建 XmlDocument 或者类似的东西,而不是与 XMLRead -对于大型文档来说,它的伸缩性不如以前,但使用起来更容易。

        2
  •  1
  •   Zenon    15 年前

    为什么不使用linq-to-xml?会使代码更可读/可维护

    XElement rssFile = XElement.Load(content);
    IEnumerable<XElement> channels = rssFile.Descendants("channel");
    foreach(XElement channel in channels)
    {
        Console.WriteLine("link: " + channel.Element("link").Value);
        Console.WriteLine("description: " + channel.Element("description").Value);
    }
    

    除此之外,乔恩所说的

        3
  •  0
  •   Thomas    15 年前

    正如jon所说,您已经读取了所有数据,所以您不能再读取它,但是,您应该能够将流的位置设置回零,然后再读取它。

    接收流。位置=0;

    我要说的另一个技巧是将变量“readstream”重命名为“reader”或其他东西,因为它是stream reader而不是stream。

    当心, 汤姆