How can I in C# call a URL which gives me a xml file, and then process that xml file for example for parsing.
To download an XML file onto your hard disk you can simply do.
XDocument doc = XDocument.Load(url);
doc.Save(filename);
How you parse it is a different matter and there are several different ways to do it. Here is a SO question that covers the subject. You can also checkout the LINQ to XML reference on MSDN.
using System;
using System.IO;
using System.Net;
using System.Text;
...
public static void GetFile
(
string strURL,
string strFilePath
)
{
WebRequest myWebRequest = WebRequest.Create(strURL);
WebResponse myWebResponse = myWebRequest.GetResponse();
Stream ReceiveStream = myWebResponse.GetResponseStream();
Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
StreamReader readStream = new StreamReader( ReceiveStream, encode );
string strResponse=readStream.ReadToEnd();
StreamWriter oSw=new StreamWriter(strFilePath);
oSw.WriteLine(strResponse);
oSw.Close();
readStream.Close();
myWebResponse.Close();
}
from : http://zamov.online.fr/EXHTML/CSharp/CSharp1.html
XML Parser:
http://www.c-sharpcorner.com/uploadfile/shehperu/simplexmlparser11292005004801am/simplexmlparser.aspx
Just pass the stream to the XML Parser.
Related
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.
I have XML with the element: <DESCRIPTION>fault – No reply</DESCRIPTION>
I am transforming the Xml from a web-service as follows based on Jon Skeet's code https://stackoverflow.com/a/427737/197229 (the original Xml validates fine):
public sealed class StringWriterUTF8 : StringWriter
{
public override Encoding Encoding
{
get { return Encoding.UTF8; }
}
}
WebRequest request = WebRequest.Create(url);
WebResponse response = request.GetResponse();
Stream stream = response.GetResponseStream();
StreamReader streamReader = new StreamReader(stream);
string xml = streamReader.ReadToEnd();
logger.Log().Debug(String.Format("Received Xml:\n{0}", xml));
if(Transform != null)
{
using (var stringReader = new StringReader(xml))
using (var xmlReader = XmlReader.Create(stringReader))
using (var stringWriter = new StringWriterUTF8())
using (var xmlTextWriter = XmlWriter.Create(stringWriter, new XmlWriterSettings()
{ Indent= true}))
{
Transform.Transform(xmlReader,xmlTextWriter);
xml = stringWriter.ToString();
logger.Log().Debug(String.Format("Transformed Xml:\n{0}", xml));
}
}
Everything looks great... but the generated XML is failing validation when I try to use it, even though to the naked eye it looks fine. If I remove that hyphen, there are no problems.
I don't understand why the original XML is fine and the .Net classes are getting tripped up, but if I try and validate the Xml in Notepad++ I get this:
Input is not proper UTF-8, indicate encoding ! Bytes: 0x96 0x20 0x4E
0x6F
How can I resolve this? All I want to do is receive Xml and transform it to a new Xml file without encoding weirdness!
I want to transfer XML from client to some server using FTP. What I get is the XmlElement object. I know that I can create the File and upload it to appropriate location (FTP).
However, I think it's better to create File in memory (to avoid file saving on the local disk).
Can someone guide me how can i achieve this?
I am using C# 4.0.
You can use FtpWebRequest.GetRequestStream() to write directly to the request stream without first saving the file on disk
Retrieves the stream used to upload data to an FTP server.
XmlElement.OuterXml returns a String representation of the XmlElement.
string xml = myXmlElement.OuterXml;
byte[] bytes = Encoding.UTF8.GetBytes(xml);
Stream requestStream = request.GetRequestStream();
requestStream.Write(bytes, 0, bytes.Length);
requestStream.Close();
Ling2Xml is easier to use:
stream = ftpRequest.GetRequestStream();
XElement xDoc = new XElement("Root",
new XElement("Item1", "some text"),
new XElement("Item2", new XAttribute("id", 666))
);
xDoc.Save(stream);
or you can use serialization
XmlSerializer ser = new XmlSerializer(typeof(SomeItem));
ser.Serialize(stream, new SomeItem());
public class SomeItem
{
public string Name;
public int ID;
}
#L.B. gave the hint to use XDocument and it solved my problem.
Here is the solution:
Write a code to create XDocument object out of the XmlElement object.
StringBuilder stringBuilder = new StringBuilder();
XmlWriter xmlWriter = new XmlTextWriter(new StringWriter(stringBuilder));
xmlElement.WriteTo(xmlWriter);
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(new StringReader(stringBuilder.ToString()));
XDocument doc = XDocument.Load(xmlDocument.CreateNavigator().ReadSubtree(), LoadOptions.PreserveWhitespace);
Then use the FTP's stream like this.
Stream ftpstream = ((FtpWebRequest)WebRequest.Create(path)).GetRequestStream();
doc.Save(ftpstream);
ftpstream.Close();
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.