StreamReader和读取XML文件

10

我使用StreamReader从Web服务器获取了一个响应...现在我想解析这个响应(它是一个XML文档文件)以获取其值,但每次尝试时都会出现错误:根元素丢失。

如果我直接读取同样的XML文件,则该文件格式良好,我可以读取它。

这是流:

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

这是我尝试读取XML文件的方式:

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(responseReader);
XmlNodeList address = xmlDoc.GetElementsByTagName("original");

1
使用 Console.Write(responseReader); 我得到了格式完美的 XML 文件,我已经将其复制粘贴到文件中并尝试手动使用我的代码读取它,也可以正常工作。 - Badr Hari
2
此外,您应该在大多数对象上使用“using”。您可能会发现WebClient比web-request/response更容易使用,或者如其中一个答案中所述,让文档只需使用Load(path)即可解决问题。 - Marc Gravell
5个回答

18
你调用了 ReadToEnd() 方法,这意味着你已经将所有数据都读取完毕并转换成字符串。这也就是说,读取器中没有更多的数据可供获取了。所以,最好不要这么做。或者,如果需要使用读取后的字符串,可以使用 LoadXml(responseString) 方法。请注意保留原文中的HTML标签格式。

6

Load 方法可以从远程资源获取 XML 文档。因此,您可以简化代码如下:

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

不需要任何Web请求、Web响应、StreamReader等(顺便说一句,你没有正确地处理它们)。如果这不起作用,可能是因为远程XML文档不是真正的XML文档,而是损坏的。

OP说他会得到“根元素丢失”的错误,这意味着响应中没有根元素,因此应该将其放在根元素中或修复响应。您当前的代码不会对当前方式进行任何更改。 - Saeed Amiri
@Saeed,不,如果您没有正确使用streamreader,则它将返回一个空字符串,XmlDocument会报错。OP首先在stream reader上调用了ReadToEnd,然后将这个相同的reader传递给了Load方法,但是因为reader已经定位到末尾,所以它没有返回任何内容。我的代码修复了它,因为我的代码只是依赖于框架中已经构建的内容。当然,正如我提到的,如果远程XML文件损坏,需要先修复它。 - Darin Dimitrov
是的,首先我认为OP在不同的代码中尝试了它们 :) 现在在接受答案后,我看到了他的错误。 - Saeed Amiri

2

如果您使用的是您在问题中粘贴的确切代码,则问题在于您首先将整个流读入字符串,然后在调用 xmlDoc.Load(responseReader) 时尝试再次读取流。

如果您已经将整个流读入字符串,请使用该字符串创建xml文档 xmlDoc.Load(responseString)


第二种用法应该是LoadXml,因为Load(string)需要一个路径,而不是xml。 - Marc Gravell

0

检查responseString的内容:可能包含一些额外的头信息,导致xml解析器无法正常工作。


-1
你收到的错误意味着,你接收到的XML缺少包装整个内容的第一个元素。尝试使用一些元素来包装你接收到的答案,例如:
   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")

希望这有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接