10

I get a response from a web-server using StreamReader... now I want to parse this response (it's an XML document file) to get its values, but every time I try to do it I get a error: Root element is missing.

If I read the same XML file directly, the file is well formatted and I can read it.

This is the stream:

WebResponse response = webRequest.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader responseReader = new StreamReader(responseStream);
string responseString = responseReader.ReadToEnd();

And this is how I try to read the XML file:

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(responseReader);
XmlNodeList address = xmlDoc.GetElementsByTagName("original");
stakx - no longer contributing
  • 83,039
  • 20
  • 168
  • 268
Badr Hari
  • 8,114
  • 18
  • 67
  • 100
  • 1
    With Console.Write(responseReader); I get prefectly formatted xml file, I have copy pasted to a file and tried to read it manually with my code also, it works. – Badr Hari Jan 30 '11 at 09:05
  • 2
    Also - you should be using `using` on most of those objects. You may find `WebClient` easier than web-request/response - or, as noted in one of the answers, let the document worry about it with just `Load(path)` – Marc Gravell Jan 30 '11 at 09:15

5 Answers5

18

You have called ReadToEnd(), hence consumed all the data (into a string). This means the reader has nothing more to give. Just: don't do that. Or, do that and use LoadXml(reaponseString).

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
6

The Load method is capable of fetching XML documents from remote resources. So you could simplify your code like this:

var xmlDoc = new XmlDocument();
xmlDoc.Load("http://example.com/foo.xml");
var address = xmlDoc.GetElementsByTagName("original");

No need of any WebRequests, WebResponses, StreamReaders, ... (which by the way you didn't properly dispose). If this doesn't work it's probably because the remote XML document is not a real XML document and it is broken.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • OP says he will get "Root element is missing" means there is no root element in response so should fall it in root element or should fix his response, your current code doesn't make any change to current manner. – Saeed Amiri Jan 30 '11 at 09:16
  • @Saeed, no, if you don't properly consume the streamreader it will return an empty string and the XmlDocument will complain. The OP first called `ReadToEnd` on the stream reader and then passed this same reader to the `Load` method but because the reader was already positioned at the end it didn't return anything. My code fixes it because all that my code do is to rely on what's already built into the framework. Of course as I mentioned if the remote XML is broken it needs to be fixed first. – Darin Dimitrov Jan 30 '11 at 09:19
  • Yes,first I think OP tries them in different codes :) and now after accepting answer I see his mistake. – Saeed Amiri Jan 30 '11 at 09:28
2

If you do it with the exact code you pasted in your question, then the problem is that you first read the whole stream into string, and then try to read the stream again when calling xmlDoc.Load(responseReader)

If you have already read the whole stream to the string, use that string to create the xml document xmlDoc.Load(responseString)

Tomas
  • 553
  • 4
  • 9
0

Check what's the content of responseString: probably it contains some additional headers that makes the xmlparser unhappy.

Felice Pollano
  • 32,832
  • 9
  • 75
  • 115
-1

The error you are getting means, that XML you receive lacks first element that wraps the whole content. Try wrapping the answer you receive with some element, for example:

   WebResponse response = webRequest.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader responseReader = new StreamReader(responseStream);
string responseString = responseReader.ReadToEnd();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXML( "<root>" + responseString + "</root>" );
XmlNodeList address = xmlDoc.GetElementsByTagName("original")

Hope this helped

Boris Modylevsky
  • 3,029
  • 1
  • 26
  • 42