tags:

views:

266

answers:

3

Why doesn't the while loop return anything? I assume this has something to do with .NET. I have .NET 2.0. The problem is that the while statement will execute one time then exit, as though there are no nodes with that name, when there definately are.

Here is an example of the XML:

<rss version="2.0">
    <channel>
        <title>...</title>
        <link>...</link>
        <description>...</description>
        <lastBuildDate>...</lastBuildDate>
        <item>
            <title>User greeting</title>
            <guid>...</guid>
            <link>http://...&lt;/link&gt;

            <description>Voicebox number: 1</description>
            <author>Free Conference Call</author>
        </item>
        <item>
            <title>User greeting</title>
            <guid>...</guid>
            <link>http://...&lt;/link&gt;

            <description>Voicebox number: 1</description>
            <author>Free Conference Call</author>
        </item>
    </channel>
</rss>

Here is the code:

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);
}
+11  A: 

You've already read all the data from the response when you call

resXML = readerStream.ReadToEnd();

... readerStream and readStream are both layered on top of receiveStream, so once you've read all the data through one, you can't read it again through the other.

You should really have a using statement for the response - and ideally the various streams involved. Given that you can create an XmlReader from a stream, not just a StreamReader, why not just use something like this:

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
       }
   }
}

Additionally, I'd generally recommend creating an XmlDocument or something similar rather than working with XmlReader - it doesn't scale as well for large documents, but it's easier to work with.

Jon Skeet
my reading streams was what did it. thanks.
Arlen Beiler
+1  A: 

why don't you use Linq-to-XML? Would make for more readable/maintainable code

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);
}

other than that, what Jon said

Zenon
A: 

Like Jon said you have already read all of the data so you cannot read it again, however, you should be able to set the position of the stream back to zero and then read it again.

receiveStream.Position = 0;

The other tip I would say is to rename your variable "readStream" to "reader" or something else because it is a StreamReader not a Stream.

Take care, Tom

Thomas
I cannot, it says that seek is disabled. Don't know why.
Arlen Beiler