I have following url which returns me XML response in c#:
http://www.bnr.ro/files/xml/years/nbrfxrates2017.xml
Now, i want to retrieve the currency in Euro for my date which is present as a paramater in my function. I want to use Linq but i have some problems
My function:
public static void getXml(String year, String data)
{
WebClient webClient = new WebClient();
string url = "http://www.bnr.ro/files/xml/years/nbrfxrates" + year + ".xml";
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(response.GetResponseStream());
XElement xe = XElement.Load(response.GetResponseStream());
var x = (from e in xe.Elements("Cube")
where e.Attribute("date").Value.Equals(data)
select e.Element("Rate") into p
where p.Element("currency").Value.Equals(data)
select p.Value);
Console.WriteLine(x.ToString());
}
My error is:
The root element is missing on XElement xe =
XElement.Load(response.GetResponseStream());
Method GetResponseStream returns a stream:
Gets the stream that is used to read the body of the response from the
server.
You cannot read this stream twice. When you load XmlDocument it reads data from network stream and closes it releasing the connection. When you try to load XElement from the closed stream, you get an error.
You should read response stream only once - e.g. into string or into MemoryStream:
string xml;
using(var reader = new StreamReader(r.GetResponseStream()))
xml = reader.ReadToEnd();
Note: It's not clear why you need XmlDocument if you are using linq to xml.
Related
Ive been using the following code to call up data coming from localhost:8080 in xml format. This part of the code works fine:
private void openP()
{
String sUrl = "http://localhost:8080/GetOpen=";
XmlTextReader rssReader = new XmlTextReader(sUrl.ToString());
XmlDocument rssDoc = new XmlDocument();
WebRequest wrGETURL;
wrGETURL = WebRequest.Create(sUrl);
Stream objStream;
objStream = wrGETURL.GetResponse().GetResponseStream();
StreamReader objReader = new StreamReader(objStream, Encoding.UTF8);
WebResponse wr = wrGETURL.GetResponse();
}
I want to know how I can now use the data that xhttp://localhost:8080/GetOpen= returns as a variable in my program.
for example if I were to goto xhttp://localhost:8080/GetOpen= in a web browser I would see this:
<Response>
<Content>
<Position Symbol="xVAR" Market="blah" >
</Content>
</Response>
how would I go about making xVar a String variable that I can just simply write to a label?
Thanks
Since you're using XmlDocument, then you can use SelectSingleNode() method passing correct XPath to get particular part of the XML :
rssDoc.Load("http://localhost:8080/GetOpen=");
.....
XmlNode symbol = rssDoc.SelectSingleNode("//Position/#Symbol");
String symbolValue = "";
if(symbol != null) symbolValue = symbol.Value;
I have an app that gets a daily feed from an external rss feed (this data is in xml).
I have a search form that allows users to search my database, however, i would like to use the same searchstring that users enter on my site to search this rss feed, then extract only whats relevant, and display that on my website.
I have been looking at reading xml file using linq using this code:
XElement xelement = XElement.Load("..\\..\\Employees.xml");
IEnumerable<XElement> employees = xelement.Elements();
Console.WriteLine("List of all Employee Names along with their ID:");
foreach (var employee in employees)
{
Console.WriteLine("{0} has Employee ID {1}",
employee.Element("Name").Value,
employee.Element("EmpId").Value);
}
the problem i have with this is, where in the code do i use a url instead of a file name:
XElement xelement = XElement.Load("..\\..\\Employees.xml");
should be:
XElement xelement = XElement.Load("http://www.test.com/file.xml");
I am thinking maybe i should store the content into an array or something, and check to make sure if the searchString is in it?
I am not sure how to proceed and whats best to use, maybe i shouldn't even use linq??
so using the responses below here is what i have done:
public void myXMLTest()
{
WebRequest request = WebRequest.Create("http://www.test.com/file.xml");
WebResponse response = request.GetResponse();
Stream dataStream = response.GetResponseStream();
XElement xelement = XElement.Load(dataStream);
IEnumerable<XElement> employees = xelement.Elements();
MessageBox.Show("List of all Employee Names along with their ID:");
foreach (var employee in employees)
{
MessageBox.Show(employee.Name.ToString());
/* the above message box gives me this:
{http://www.w3.org/2005/Atom}id
{http://www.w3.org/2005/Atom}name
{http://www.w3.org/2005/Atom}title
etc
*/
MessageBox.Show(employee.Element("name").Value);//this gives me error
}
}
You're going to have to do a bit more work than just providing it a URL.
Instead, you're going to need to get the XML file using the WebRequest class. Provided the request is successful, you can then turn around use that as your argument to XElement.Load.
Example (illustrative only, for the love of Pete add some error handling):
WebRequest request = WebRequest.Create("http://www.test.com/file.xml");
WebResponse response = request.GetResponse();
Stream dataStream = response.GetResponseStream();
XElement doc = Xelement.Load(dataStream);
I am calling a third party service and they send the response as Xml. However, as I am using WebClient to call the service the response I get is a byte array.
var client = new WebClient();
var result = client.UploadValues(post_url, data);
result is a byte array. How do I convert it to XML to read the response given by the third party service?
You can turn the bytes into a string:
string xml = Encoding.UTF8.GetString(result);
and then parse it :
XDocument doc = XDocument.Parse(xml);
Use a MemoryStream:
using (var stream = new MemoryStream(result))
{
var doc = XDocument.Load(stream);
...
}
I have some code:
WebRequest request = HttpWebRequest.Create(url);
WebResponse response = request.GetResponse();
using (System.IO.StreamReader sr =
new System.IO.StreamReader(response.GetResponseStream()))
{
System.Xml.Linq.XDocument doc = new System.Xml.Linq.XDocument();
doc.Load(new System.IO.StringReader(sr.ReadToEnd()));
}
I can't load my response in my XML document. I get the following error:
Member 'System.XMl.Linq.XDocument.Load(System.IO.TextReader' cannot be accessed
with an instance reference; qualify it with a type name instead.
This is becoming really frustrating. What am I doing wrong?
Unlike XmlDocument.Load, XDocument.Load is a static method returning a new XDocument:
XDocument doc = XDocument.Load(new StringReader(sr.ReadToEnd()));
It seems pretty pointless to read the stream to the end then create a StringReader though. It's also pointless creating the StreamReader in the first place - and if the XML document isn't in UTF-8, it could cause problems. Better:
For .NET 4, where there's an XDocument.Load(Stream) overload:
using (var response = request.GetResponse())
{
using (var stream = response.GetResponseStream())
{
var doc = XDocument.Load(stream);
}
}
For .NET 3.5, where there isn't:
using (var response = request.GetResponse())
{
using (var stream = response.GetResponseStream())
{
var doc = XDocument.Load(XmlReader.Create(stream));
}
}
Or alternatively, just let LINQ to XML do all the work:
XDocument doc = XDocument.Load(url);
EDIT: Note that the compiler error did give you enough information to get you going: it told you that you can't call XDocument.Load as doc.Load, and to give the type name instead. Your next step should have been to consult the documentation, which of course gives examples.
I use the StreamReader class to obtain XML for my GeoCoding process from Google.
StreamReader srGeoCode = new StreamReader(WebRequest.Create(Url).GetResponse().GetResponseStream());
String GeoCodeXml = srGeoCode.ReadToEnd();
XmlDocument XmlDoc = new XmlDocument();
GeoCode oGeoCode = new GeoCode();
XmlDoc.Load(GeoCodeXml);
I get XML back but it adds \n and other extras to the XML
<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<kml xmlns=\"http://earth.google.com/kml/2.0\"><Response>\n <name>
I have the same code in VB and it does not do this. I can successfully GeoCode my information using the VB version of this console app.
Is there a reason the C# version adds this extra data to the XML that I retrieve back? I am trying my best to convert everything over to C#. I enjoy coding in it over VB.
Here is the VB Code:
Dim wreqGeoCode As WebRequest = WebRequest.Create(strURL)
Dim wresGeoCode As WebResponse = wreqGeoCode.GetResponse
Dim srGeoCode As New StreamReader(wresGeoCode.GetResponseStream())
Dim strXML As String = srGeoCode.ReadToEnd()
Dim xmlDoc As New XmlDocument
xmlDoc.LoadXml(strXML)
You need XmlDoc.LoadXml if you're going to load a string. Load loads from a file.
BTW, the alternative is also more efficient. You can load the document directly from the stream:
WebRequest webRequest = WebRequest.Create(Url);
using (WebResponse webResponse = webRequest.GetResponse())
{
using (Stream responseStream = webResponse.GetResponseStream())
{
XmlDocument XmlDoc = new XmlDocument();
GeoCode oGeoCode = new GeoCode();
XmlDoc.Load(responseStream);
}
}
The using statements ensure that the WebResponse and Stream get cleaned up, even if an exception is thrown.
y not just do
GeoCodeXml=GeoCodeXml.Replace("\n","");
if it is truly returning the \n as mentioned here.