C# Can't read a XML Array and the Nodes within - c#

I'm trying to read the following response. The green line states the node I need to read:
I need to read the 3rd 'result' item ALWAYS
My Code:
string location = "";
string url = "http://maps.googleapis.com/maps/api/geocode/xml?" + latitude + "," + longitude + "&sensor=true";
XmlDocument doc1 = new XmlDocument();
doc1.Load(url);
XmlElement root = doc1.DocumentElement;
XmlNodeList nodes = root.SelectNodes("/GeocodeResponse[0]");
foreach (XmlNode node in nodes)
{
location = node["formatted_address"].InnerText;
}
The code doesn't give me any nodes in fact the the Node count is 0. What am I doing wrong?

The problem is in Xpath expression. To get all ther result nodes use this:
XmlNodeList nodes = root.SelectNodes("/GeocodeResponse/result");
If you want only the third result node you can use SelectSingleNode method:
var node = root.SelectSingleNode("/GeocodeResponse/result[3]");
location = node["formatted_address"].InnerText;
Update
The initial problem is in you url.You forgot latlng= part. This is an example of working url:
https://maps.googleapis.com/maps/api/geocode/xml?latlng=40.714224,-73.961452&sensor=true
Also there could be a problem with number format, if your sytem properties have , as a double delimeter. You can use InvariantCulture to solve this. So the working example would be:
double latitude = 40.714224;
double longitude = -73.961452;
string url = String.Format(System.Globalization.CultureInfo.InvariantCulture,
"http://maps.googleapis.com/maps/api/geocode/xml?latlng={0},{1}&sensor=true",
latitude,
longitude);
XmlDocument doc = new XmlDocument();
doc.Load(url);
XmlElement root = doc.DocumentElement;
var node = root.SelectSingleNode("/GeocodeResponse/result[3]");
var location = node["formatted_address"].InnerText;

Related

Display single value Of FirstChild Elements in XML

Please, Help me Out Here
I Want to display the value of "email" from xml. my syntax works for now but it displays every value. i want to be able to display Individual (one) Values like
email: mail#mail.com
My scripts
var xml ="<?xml version='1.0' encoding='UTF-8'?>
<MemResponse>
<Phone>2554535</Phone>
<Email>mail#mail</Email>
<Number>we75546654</Number>
</MemResponse>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
foreach(XmlNode n in doc.DocumentElement)
{
string q = n.FirstChild.InnerText;
Response.Write(q);
}
Simply you can select all element by tag name by GetElementsByTagName method.
Check this :
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
var myEmails = doc.GetElementsByTagName("Email");
foreach (XmlNode mail in myEmails)
{
string mailText = mail.FirstChild.InnerText;
Response.Write(mailText);
}
I have got it from MSDN
Your code goes through each node and writes the contents of that node.
It seems like you want to match on the node name, and only write the value if its name is "email".
If thats the case, inside of your for each, try something like:
if(n.Name == "Email") {
string q = n.FirstChild.InnerText;
Response.Write(q);
}
Alternatively, you could just use a node list.
NodeList nl = doc.GetElementsByTagName("Email");
And write that.
When loading your XML Doc, use :
HttpWebRequest request = WebRequest.Create(requestUrl) as HttpWebRequest;
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(response.GetResponseStream());
Please try this code:
XmlDocument doc = new XmlDocument();
doc.LoadXml("YOUR_XML_PATH");
XmlNodeList email_hd= doc.GetElementsByTagName("Email");
string email=email_hd[0].InnerText;

C# XmlDocument select nodes returns empty

i am trying to work with http://api.met.no/weatherapi/locationforecast/1.9/?lat=49.8197202;lon=18.1673554 XML.
Lets say i want to select all value attribute of each temperature element.
i tried this.
const string url = "http://api.met.no/weatherapi/locationforecast/1.9/?lat=49.8197202;lon=18.1673554";
WebClient client = new WebClient();
string x = client.DownloadString(url);
XmlDocument xml = new XmlDocument();
xml.LoadXml(x);
XmlNodeList nodes = xml.SelectNodes("/weatherdata/product/time/location/temperature");
//XmlNodeList nodes = xml.SelectNodes("temperature");
foreach (XmlNode node in nodes)
{
Console.WriteLine(node.Attributes[0].Value);
}
But i get nothing all the time. What am i doing wrong?
The current single slash is targeting weatherdata under the root but the root is weatherdata.
Add a preceding slash to your xpath query to make it a double slash:
XmlNodeList nodes = xml.SelectNodes("//weatherdata/product/time/location/temperature");
Double slashes tells xpath to select nodes in the document from the current node that match the selection no matter where they are.
or remove the preceding slash:
XmlNodeList nodes = xml.SelectNodes("weatherdata/product/time/location/temperature");
which looks for the whole path including the root.
Also, since you apparently want the value called value add this:
Console.WriteLine(node.Attributes["value"].Value);
Since the value at of node.Attributes[0].Value may not be in the order you expect.
Are you attempting to loop through each attribute?
foreach (XmlNode node in nodes)
{
//You could grab just the value like below
Console.WriteLine(node.Attributes["value"].Value);
//or loop through each attribute
foreach (XmlAttribute f in node.Attributes)
{
Console.WriteLine(f.Value);
}
}

How to get the sibling of an xml node

I have an xml file as below
<Games>
<Game>
<name>Tzoker</name>
<file>tzoker1</file>
</Game>
<Game>
<file>lotto770</file>
</Game>
<Game>
<name>Proto</name>
<file>proto220</file>
</Game>
</Games>
I want to get the values of name and file items for every Game node.
It is easy by using this query.
string query = String.Format("//Games/Game");
XmlNodeList elements1 = xml.SelectNodes(query);
foreach (XmlNode xn in elements1)
{
s1 = xn["name"].InnerText;
s2 = xn["file"].InnerText;
}
The problem is that there are some nodes that they don't have the name item. So the code above doesn't work.
I have solved the problem by using the following code
string query = String.Format("//Games/Game/name");
XmlNodeList elements1 = xml.SelectNodes(query);
foreach (XmlNode xn in elements1)
{
s1 = xn.InnerText;
string query1 = String.Format("//Games/Game[name='{0}']/file", s1);
XmlNodeList elements2 = xml.SelectNodes(query1);
foreach (XmlNode xn2 in elements2)
{
s2 = xn2.InnerText;
}
}
The problem is that there is a case that two or more nodes have the same name value. So, the s2 variable will get the file value of the last node that the loop finds. So, I would like to find a way to get the sibling file value of the current name item. How could I do it? I try do move to the parent node of the current node and then to move to the file item but without success by using the following code.
string query = String.Format("//Games/Game/name");
XmlNodeList elements1 = xml.SelectNodes(query);
foreach (XmlNode xn in elements1)
{
s1 = xn.InnerText;
string query1 = String.Format("../file");
XmlNodeList elements2 = xml.SelectNodes(query1);
foreach (XmlNode xn2 in elements2)
{
s2 = xn2.InnerText;
}
}
I hope there is a solution.
You can use Game[name] to filter Game elements to those with child element name. This is possible because child:: is the default axes which will be implied when no explicit axes mentioned. Extending this further to check for child element file as well, would be as simple as Game[name and file] :
string query = String.Format("//Games/Game[name]");
XmlNodeList elements1 = xml.SelectNodes(query);
foreach (XmlNode xn in elements1)
{
s1 = xn["name"].InnerText;
s2 = xn["file"].InnerText;
}
Now to answer your question literally, you can use following-sibling:: axes to get sibling element that follows current context element. So, given the context element is name, you can do following-sibling::file to return the sibling file element.
Your attempt which uses ../file should also work. The only problem was, that your code executes that XPath on xml, the XmlDocument, instead of executing it on current name element :
XmlNodeList elements2 = xn.SelectNodes("../file");
If I understand you correctly you want to find all games that have a name. You can do that using XPath. Here is a solution that uses LINQ to XML. I find that easier to work with than XmlDocument:
var xDocument = XDocument.Parse(xml);
var games = xDocument
.Root
.XPathSelectElements("Game[child::name]")
.Select(
gameElement => new {
Name = gameElement.Element("name").Value,
File = gameElement.Element("file").Value
}
);
The XPath to select all <Game> elements that have a <name> child element is Game[child::name].

Get City Name from Reverse Geocoding with latitude and longitude

http://maps.googleapis.com/maps/api/geocode/xml?latlng=39.952853,32.901470&sensor=false
In this xml url, I couldn't get data from area which is explained in the below.
<long_name>Altınevler Mahallesi</long_name>
I'm using asp.net c#. Could you help me with this?
This is the code I tried to get the data from xml
XmlDocument xdoc = new XmlDocument();
xdoc.Load(
"http://maps.googleapis.com/maps/api/geocode/xml?latlng=39.952853,32.901470&sensor=false"
);
XmlNodeList xNodelst = xdoc.DocumentElement.SelectNodes("entry");
foreach (XmlNode xNode in xNodelst)
{
label1.Text += "read";
}
I solved my question if anyone wants know be my guess. Solution indicated in the below.
Thank you
XmlDocument xDoc = new XmlDocument();
xDoc.Load("https://maps.googleapis.com/maps/api/geocode/xml?latlng=" +coordinate+"&location_type=ROOFTOP&result_type=street_address&key=YOURAPIKEY");
XmlNodeList xNodelst = xDoc.GetElementsByTagName("result");
XmlNode xNode = xNodelst.Item(0);
string adress = xNode.SelectSingleNode("formatted_address").InnerText;
string mahalle = xNode.SelectSingleNode("address_component[3]/long_name").InnerText;
string ilce = xNode.SelectSingleNode("address_component[4]/long_name").InnerText;
string il = xNode.SelectSingleNode("address_component[5]/long_name").InnerText;
so you can pull anydata for google maps.

Get partial data of XML file

I have this xml file which contains information from tagchimp, but the file contains way to much information. How do i only load the information i need. I have found some code:
XmlDocument doc = new XmlDocument();
doc.Load(path);
XmlElement root = doc.DocumentElement;
XmlNodeList nodes = root.SelectNodes("movie");
foreach (XmlNode node in nodes)
{
string date = node["tagChimpID"].InnerText;
string name = node["locked"].InnerText;
Console.WriteLine("Id:" + date + " Locked:" + name);
}
but it only loads the elements not the child elements, some for example movieTitle or shortDescription
I found a way:
public static string Test(string path, XmlElement nodes)
{
string Name = "";
string releaseDate = "";
XmlNodeList xnList = nodes.SelectNodes("/items/movie");
XmlNode eNode;
foreach (XmlNode xn in xnList)
{
eNode = xn.SelectSingleNode("movieTags/info/movieTitle");
if (eNode != null)
{
Name = eNode.InnerText;
}
eNode= xn.SelectSingleNode("movieTags/info/releaseDate");
releaseDate = eNode.InnerText;
}
but it's not the most practical way to come by it.
Since you are using .NET, you might spend some time learning LINQ to XML, since it sounds like it would do what you want.
There is a lot of online documentation, in particular how to do various basic queries to get information from specific nodes: http://msdn.microsoft.com/en-us/library/bb943906.aspx
You could also get the same results with XPath.
Or you could manually traverse the nodes, although you would have to handle the child nodes properly (as you already discovered).

Categories