C# Pull XML data from google's weather API - c#

I've been using this code to try and get data from the google weather API, but I never get even close to pulling out what i want.
My goal is to look at:
<forecast_information>
**<city data="london uk"/>**
<postal_code data="london uk"/>
<latitude_e6 data=""/>
<longitude_e6 data=""/>
<forecast_date data="2011-10-09"/>
<current_date_time data="2011-10-09 12:50:00 +0000"/>
<unit_system data="US"/>
</forecast_information>
<current_conditions>
<condition data="Partly Cloudy"/>
<temp_f data="68"/>
**<temp_c data="20"/>**
**<humidity data="Humidity: 68%"/>**
<icon data="/ig/images/weather/partly_cloudy.gif"/>
**<wind_condition data="Wind: W at 22 mph"/>**
</current_conditions>
And only return the text of the child nodes.
So the result would be:
City: London UK
Temp: 20c
Humidity: 68%
Wind: 22mph
Currently I am trying to use this, but got nowhere...
XmlDocument doc = new XmlDocument();
XmlNodeList _list = null;
doc.Load("http://www.google.com/ig/api?weather=london+uk");
_list = doc.GetElementsByTagName("forecast_information/");
foreach (XmlNode node in _list)
{
history.AppendText(Environment.NewLine + "City : " + node.InnerText);
}
//NOTE, currently code is set to display ALL child nodes
Perhaps someone can shed some light on the matter?

Maybe you should use node.SelectSingleNode("city").Attributes["data"].Value instead of node.InnerText
--EDIT--
This works for me
XmlDocument doc = new XmlDocument();
doc.Load("http://www.google.com/ig/api?weather=london+uk");
var list = doc.GetElementsByTagName("forecast_information");
foreach (XmlNode node in list)
{
Console.WriteLine("City : " + node.SelectSingleNode("city").Attributes["data"].Value);
}
list = doc.GetElementsByTagName("current_conditions");
foreach (XmlNode node in list)
{
foreach (XmlNode childnode in node.ChildNodes)
{
Console.Write(childnode.Attributes["data"].Value + " ");
}
}

Change that to
history.AppendText(Environment.NewLine + "City : " + node.GetAttribute("data"));

using System.Xml.Linq;
using System.Xml.XPath;
XElement doc = XElement.Load("http://www.google.com/ig/api?weather=london+uk");
string theCity = doc.XPathSelectElement(#"weather/forecast_information/city").Attribute("data").Value;
string theTemp = doc.XPathSelectElement(#"weather/current_conditions/temp_c").Attribute("data").Value;
string theHumid = doc.XPathSelectElement(#"weather/current_conditions/humidity").Attribute("data").Value;
string theWind = doc.XPathSelectElement(#"weather/current_conditions/wind_condition").Attribute("data").Value;
string resultString = String.Format("City : {0} Temp : {1}c {2} {3}", theCity, theTemp, theHumid, theWind);

Related

Concatenate values from the same nodes for each employee individ in XML

I am beginner in programming. I have a scenario like this:
For each unique application member, I want to return a new XML that contains for each EMPLOYEE_MEMBER_INDIVID all concatenated values of EMPLOYEE_MEMBER_INDIVID_ROLE_ON_APPLICATION field.
Roles should be concatenated for each MEMBER_UNIQID from APPLICATION_MEMBER nodes.
<EMPLOYEE_MEMBER_INDIVID>
<EMPLOYEE_MEMBER_INDIVID_MAIN_DATA ENTITY="">
<EMPLOYEE_MEMBER_INDIVID_UNIQ_ID>096788</EMPLOYEE_MEMBER_INDIVID_UNIQ_ID>
<EMPLOYEE_MEMBER_INDIVID_NAME>Dina</EMPLOYEE_MEMBER_INDIVID_NAME>
<EMPLOYEE_MEMBER_INDIVID_SURNAME>Gomez</EMPLOYEE_MEMBER_INDIVID_SURNAME>
</EMPLOYEE_MEMBER_INDIVID_MAIN_DATA>
<EMPLOYEE_MEMBER_INDIVID_ROLE_DATA_S>
<EMPLOYEE_MEMBER_INDIVID_ROLE_DATA ENTITY="">
<EMPLOYEE_MEMBER_INDIVID_ROLE_ON_APPLICATION>Co-borrower</EMPLOYEE_MEMBER_INDIVID_ROLE_ON_APPLICATION>
</EMPLOYEE_MEMBER_INDIVID_ROLE_DATA>
<EMPLOYEE_MEMBER_INDIVID_ROLE_DATA ENTITY=""> <EMPLOYEE_MEMBER_INDIVID_ROLE_ON_APPLICATION>Guarantor</EMPLOYEE_MEMBER_INDIVID_ROLE_ON_APPLICATION>
</EMPLOYEE_MEMBER_INDIVID_ROLE_DATA>
<EMPLOYEE_MEMBER_INDIVID_ROLE_DATA ENTITY="">
<EMPLOYEE_MEMBER_INDIVID_ROLE_ON_APPLICATION>Mortgager individual</EMPLOYEE_MEMBER_INDIVID_ROLE_ON_APPLICATION>
</EMPLOYEE_MEMBER_INDIVID_ROLE_DATA>
</EMPLOYEE_MEMBER_INDIVID_ROLE_DATA_S>
</EMPLOYEE_MEMBER_INDIVID>
The output node should be:
<EMPLOYEE_MEMBER_INDIVID>
<EMPLOYEE_MEMBER_INDIVID_MAIN_DATA ENTITY="">
<EMPLOYEE_MEMBER_INDIVID_UNIQ_ID>096788</EMPLOYEE_MEMBER_INDIVID_UNIQ_ID>
<EMPLOYEE_MEMBER_INDIVID_NAME>Dina</EMPLOYEE_MEMBER_INDIVID_NAME>
<EMPLOYEE_MEMBER_INDIVID_SURNAME>Gomez</EMPLOYEE_MEMBER_INDIVID_SURNAME>
</EMPLOYEE_MEMBER_INDIVID_MAIN_DATA>
<EMPLOYEE_MEMBER_INDIVID_ROLE_DATA_S>
<EMPLOYEE_MEMBER_INDIVID_ROLE_DATA ENTITY="">
<EMPLOYEE_MEMBER_INDIVID_ROLE_ON_APPLICATION>Co-borrower / Guarantor / Mortgager individual</EMPLOYEE_MEMBER_INDIVID_ROLE_ON_APPLICATION>
</EMPLOYEE_MEMBER_INDIVID_ROLE_DATA>
</EMPLOYEE_MEMBER_INDIVID_ROLE_DATA_S>
</EMPLOYEE_MEMBER_INDIVID>
My code is:
static void Main(string[] args)
{
try
{
//Create A XML Document Of Response String
XmlDocument xmlDoc = new XmlDocument();
//Read the XML File
XmlNodeList nodeList2 = xmlDoc.SelectNodes("//EMPLOYEE_MEMBER_S/EMPLOYEE_MEMBER" +
"[(EMPLOYEE_MEMBER_INDIVID/EMPLOYEE_MEMBER_INDIVID_ROLE_DATA_S/EMPLOYEE_MEMBER_INDIVID_ROLE_DATA/EMPLOYEE_MEMBER_INDIVID_ROLE_ON_APPLICATION ='Borrower' " +
"or EMPLOYEE_MEMBER_INDIVID/EMPLOYEE_MEMBER_INDIVID_ROLE_DATA_S/EMPLOYEE_MEMBER_INDIVID_ROLE_DATA/EMPLOYEE_MEMBER_INDIVID_ROLE_ON_APPLICATION='Mortgager' " +
"or EMPLOYEE_MEMBER_INDIVID/EMPLOYEE_MEMBER_INDIVID_ROLE_DATA_S/EMPLOYEE_MEMBER_INDIVID_ROLE_DATA/EMPLOYEE_MEMBER_INDIVID_ROLE_ON_APPLICATION='Co-borrower')]");
List<string> baseMemberUNIQ_IDs = new List<string>();
List<LoanMember> infos = new List<LoanMember>();
XmlNodeList baseMembersList = xmlDoc.SelectNodes("//APPLICATION_MEMBERS/APPLICATION_MEMBER[ROLE='Borrower' or ROLE='Mortgager individual' or ROLE='Co-borrower']");
foreach (XmlNode xmlNode in baseMembersList)
{
baseMemberUNIQ_IDs.Add(xmlNode["MEMBER_UNIQ_ID"].InnerText);
}
var distinctBaseMembersUNIQ_ID = baseMemberUNIQ_IDs.Distinct();
foreach (var UNIQ_ID in distinctBaseMembersUNIQ_ID)
{
XmlNodeList nodeList = xmlDoc.SelectNodes("//EMPLOYEE_MEMBER_S/EMPLOYEE_MEMBER" +
"[(EMPLOYEE_MEMBER_INDIVID/EMPLOYEE_MEMBER_INDIVID_ROLE_DATA_S/EMPLOYEE_MEMBER_INDIVID_ROLE_DATA/EMPLOYEE_MEMBER_INDIVID_ROLE_ON_APPLICATION ='Borrower' " +
"or EMPLOYEE_MEMBER_INDIVID/EMPLOYEE_MEMBER_INDIVID_ROLE_DATA_S/EMPLOYEE_MEMBER_INDIVID_ROLE_DATA/EMPLOYEE_MEMBER_INDIVID_ROLE_ON_APPLICATION='Mortgager individual' " +
"or EMPLOYEE_MEMBER_INDIVID/EMPLOYEE_MEMBER_INDIVID_ROLE_DATA_S/EMPLOYEE_MEMBER_INDIVID_ROLE_DATA/EMPLOYEE_MEMBER_INDIVID_ROLE_ON_APPLICATION='Co-borrower') " +
"and EMPLOYEE_MEMBER_INDIVID/EMPLOYEE_MEMBER_INDIVID_MAIN_DATA/EMPLOYEE_MEMBER_INDIVID_UNIQ_ID=" + UNIQ_ID.ToString() + "]");
foreach (XmlNode xmlNode2 in nodeList)
{
String ROLE = "";
foreach (XmlNode childNode in xmlNode2)
{
ROLE = childNode.ChildNodes[0].InnerXml;
Console.WriteLine("CONCATED ROLES ARE " + ROLE);
// All roles of each employee individ should be concatenated inside the first node EMPLOYEE_MEMBER_INDIVID_ROLE_ON_APPLICATION node, Other nodes shoud be removed/
}
}
}
}
catch
{
throw;
}
Console.ReadKey();
}
}
In the following url is input document XML: https://codebeautify.org/xmlviewer/cb7a26e5
Thank you for your help!
Try following xml linq :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
List<XElement> EMPLOYEE_MEMBER_INDIVID_ROLE_DATA_S = doc.Descendants("EMPLOYEE_MEMBER_INDIVID_ROLE_DATA_S").ToList();
foreach (XElement EMPLOYEE_MEMBER_INDIVID_ROLE_DATA in EMPLOYEE_MEMBER_INDIVID_ROLE_DATA_S)
{
string[] roles = EMPLOYEE_MEMBER_INDIVID_ROLE_DATA.Descendants("EMPLOYEE_MEMBER_INDIVID_ROLE_ON_APPLICATION").Select(x => (string)x).ToArray();
XElement newEMPLOYEE_MEMBER_INDIVID_ROLE_DATA = new XElement("EMPLOYEE_MEMBER_INDIVID_ROLE_DATA", new object[] {
new XAttribute("ENTITY", ""),
new XElement("EMPLOYEE_MEMBER_INDIVID_ROLE_ON_APPLICATION", string.Join(" / ", roles))
});
EMPLOYEE_MEMBER_INDIVID_ROLE_DATA.ReplaceWith(newEMPLOYEE_MEMBER_INDIVID_ROLE_DATA);
}
}
}
}

Can't get XML node when using namespace

I looked everywhere and can't read the value of an XML node that has a namespace prefix when using the namespace manager.
XmlDocument rssXmlDoc = new XmlDocument();
rssXmlDoc.Load("https://www.kijiji.ca/rss-srp-batterie-percussion/quebec/c612l9001");
StringBuilder rssContent = new StringBuilder();
XmlNamespaceManager nsmgr = new XmlNamespaceManager(rssXmlDoc.NameTable);
nsmgr.AddNamespace("dc", #"http://schemas.microsoft.com/office/infopath/2003/myXSD/2005-08-25T08-37-41");
nsmgr.AddNamespace("g-core", #"http://schemas.microsoft.com/office/infopath/2003/myXSD");
XmlNodeList rssNodes = rssXmlDoc.SelectNodes("rss/channel/item");
// Iterate through the items in the RSS file
foreach (XmlNode rssNode in rssNodes)
{
String itemsForList = "";
XmlNode rssSubNodeTitle = rssNode.SelectSingleNode("title");
XmlNode rssSubNodePrice = rssNode.SelectSingleNode("g-core:price", nsmgr);
if (rssSubNodeTitle != null && rssSubNodeTitle.InnerText != "")
{
itemsForList = rssSubNodeTitle.InnerText;
if (rssSubNodePrice != null) { itemsForList += " (" + rssSubNodePrice.InnerText + ")"; }
}
listBox1.Items.Add(WebUtility.HtmlDecode(itemsForList));
}
The URI for the g-core namespace was wrong. It works for me when corrected to the following:
nsmgr.AddNamespace("g-core", #"http://base.google.com/ns/1.0");
When debugging these things it's helpful to save the XML to a local file and examine it in Visual Studio, Code, etc.

how to extract particular attribute from xml file using c#?

static void Main(string[] args)
{
WebClient _httpReq = new WebClient(); // to talk to the web only for get method
string response = _httpReq.DownloadString("https://open-ic.epic.com/FHIR/api/FHIR/DSTU2/Patient?family=Argonaut&given=Jason");
Console.WriteLine(response);\\prints the xml string fetched from FHIR provider EPIC
XmlDocument xml = new XmlDocument();
xml.LoadXml(response); // suppose that myXmlString contains "<Names>...</Names>"
XmlNodeList xnList = xml.SelectNodes("/entry/resource/patient/name");
// here code is trying to extract the name attribute
foreach (XmlNode xn in xnList)
{
string firstName = xn["family value"].InnerText;
string lastName = xn["given value"].InnerText;
Console.WriteLine("Name: {0} {1}", firstName, lastName);
//print the first name and last name of the patient
}
Console.ReadLine();
}
i do it like this:
XmlDocument MyDocument = new XmlDocument();
MyDocument.Load("...");
XmlNode MyNode = MyDocument.SelectSingleNode("/Node_Name");
foreach (XmlAttribute MyAttribute in MyNode.Attributes)
{
if (MyAttribute.Name == "Attribute_Name")
{
object Value = MyAttribute.Value;
break;
}
}
Review XPath. Once you start understanding it, you will find it efficient and easier to code than iterating through lists. It also lets you directly get the nodes/attributes you want.
Then the code would be something similar to
string attrVal = doc.SelectSingleNode("/entry/resource/patient/#name").Value;
Or you can Load XML in XMlDocument and You can fetch element and out of that element you can read specific atairbute,
XmlDocument doc = new XmlDocument();
doc.LoadXml("<reply success=\"true\">More nodes go here</reply>");
XmlElement root = doc.DocumentElement;
string s = root.Attributes["success"].Value;

Getting detail of XML node when I have found the relevant parent node?

I'm almost getting there, but I need some help.
This is the code that I use to process our XML file. I'm able to find the section that I need to store; I just don't know how to save it.
XmlDocument doc = new XmlDocument();
doc.XmlResolver = null;
doc.Load(#"c:\xml\Sales.xml");
XmlElement root = doc.DocumentElement;
XmlNodeList nodes = root.SelectNodes("nd/ni/nv/noid");
foreach (XmlNode node in nodes)
{
if (node.OuterXml.IndexOf("Server=1,Function=1,Location=") > 0)
{
Console.WriteLine(node.OuterXml);
// This prints out "<noid>Server=1,Function=1,Location=24</noid>"
// How do I read the four <r> nodes within this <noid>?
// The values would be [124, 2, 43, 90]
}
}
The xml looks something like this:
<nd>
<ni>
<nv>
<noid>Managed=1,Network=1,smtp=1</noid>
<r>27</r>
<r>4</r>
</nv>
<nv>
<noid>Managed=1,Network=1,Ibc=1</noid>
<r>8</r>
<r>2</r>
</nv>
<nv>
<noid>Server=1,Function=1,Location=24</noid>
<r>124</r>
<r>2</r>
<r>43</r>
<r>90</r>
</nv>
<nv>
<noid>Unmanaged=9,Label=7,Place=5</noid>
<r>10</r>
<r>20</r>
</nv>
</ni>
</nd>
Console.WriteLine prints the correct <noid> text, so I know that I've already found the section with the relevant data.
My question is, how can I read the four <r> inside this <noid>? Ideally, within the IF statement, how can I read all the <r> elements that are between the <nv></nv>?
Thanks.
Using Linq-to-xml
var xmlText = File.ReadAllText(#"C:\YourDirectory\YourFile.xml");
var xDoc = XDocument.Parse(xmlText);
var rValues = new List<string>(); //THIS IS YOUR RESULT
var nvNodes = xDoc.Descendants("nv");
foreach(var el in nvNodes)
{
if (el.Element("noid").Value.Contains("Server=1,Function=1,Location="))
rValues = el.Elements("r").Select(e => e.Value).ToList();
}
Or, replacing the foreach with Linq (fails if First() is not satisfied)
var rValues = nvNodes.
First(nv => nv.Value.Contains("Server=1,Function=1,Location="))
.Elements("r")
.Select(r => r.Value);
A non-optimized, non-linq solution
XmlDocument doc = new XmlDocument();
doc.XmlResolver = null;
doc.Load(#"C:\YourDirectory\YourFile.xml");
var rValues = new List<string>(); //THIS IS YOUR RESULT
XmlElement root = doc.DocumentElement;
XmlNodeList nodes = root.SelectNodes("//nd/ni/nv");
foreach (XmlNode node in nodes)
{
if (node.FirstChild.InnerText.Contains("Server=1,Function=1,Location="))
{
foreach(XmlNode childnode in node.ChildNodes)
{
if (childnode.Name == "r")
rValues.Add(childnode.InnerText);
}
}
}
Try this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string input =
"<nd>" +
"<ni>" +
"<nv>" +
"<noid>Managed=1,Network=1,smtp=1</noid>" +
"<r>27</r>" +
"<r>4</r>" +
"</nv>" +
"<nv>" +
"<noid>Managed=1,Network=1,Ibc=1</noid>" +
"<r>8</r>" +
"<r>2</r>" +
"</nv>" +
"<nv>" +
"<noid>Server=1,Function=1,Location=24</noid>" +
"<r>124</r>" +
"<r>2</r>" +
"<r>43</r>" +
"<r>90</r>" +
"</nv>" +
"<nv>" +
"<noid>Unmanaged=9,Label=7,Place=5</noid>" +
"<r>10</r>" +
"<r>20</r>" +
"</nv>" +
"</ni>" +
"</nd>";
XElement nd = XElement.Parse(input);
var results = nd.Descendants("nv").Select(x => new
{
noid = (string)x.Element("noid"),
r = x.Elements("r").Select(y => (int)y).ToList()
}).ToList();
}
}
}
​
A short, but difficult to understand XPath expression:
XmlNodeList rNodes = root.SelectNodes(
"nd/ni/nv[noid/text()[contains(.,'Server=1,Function=1,Location=')]]/r");
foreach (XmlNode rNode in rNodes)
Console.WriteLine(rNode.InnerText);

C# : Modify a xml node

i have that xml file :
<?xml version="1.0" encoding="utf-8"?>
<reminders>
<reminder>
<Title>Alarm1</Title>
<Description>Desc1</Description>
<Time>03/07/2012 10:11AM</Time>
<snooze>1</snooze>
<repeat>None</repeat>
</reminder>
</reminders>
And i want to modify the innertext from Alarm1 to another value so i wrote that code which actually duplicate the entire node .
XmlDocument xml = new XmlDocument();
xml.Load("0.xml");
XmlNodeList elements = xml.SelectNodes("//reminders");
foreach (XmlNode element in elements)
{
if (element.InnerText == "Alarm1")
{
XmlNode newvalue = xml.CreateElement("MODIFIED");
element.ReplaceChild(newvalue, element);
xml.Save("0.xml");
}
}
And then tried another code :
foreach (XmlElement element in xml.SelectNodes("//reminder"))
{
if (element.InnerText == "Alarm1")
{
XmlNode newvalue = xml.CreateElement("MODIFIED");
element.ReplaceChild(newvalue, element);
xml.Save("0.xml");
}
}
But also doesn`t work....
EDIT 1 : [Figured out a new code]
XmlDocument xml = new XmlDocument();
xml.Load("0.xml");
foreach (XmlElement element in xml.SelectNodes("//reminder"))
{
foreach (XmlElement element1 in element)
{
if (element.SelectSingleNode("//Title").InnerText == "Alarm1")
{
XmlNode newvalue = xml.CreateElement("MODIFIED");
element.ReplaceChild(newvalue, element1);
xml.Save("0.xml");
}
}
}
But it made the Alarm1 becomes
<MODIFIED />
EDIT 2 : [I SOLVED IT :D]
Okay here is the code i could figure out :
XmlDocument xml = new XmlDocument();
xml.Load("0.xml");
foreach (XmlElement element in xml.SelectNodes("//reminder"))
{
foreach (XmlElement element1 in element)
{
if (element.SelectSingleNode("//Title").InnerText == "Alarm1")
{
MessageBox.Show(element1.InnerText);
XmlNode newvalue = xml.CreateElement("Title");
newvalue.InnerText = "MODIFIED";
element.ReplaceChild(newvalue, element1);
xml.Save("0.xml");
}
}
}
I`ll really appreciate your helps and thanks.
Try this:
xml.SelectSingleNode("//reminder/Title").InnerText = "NewValue";
Your foreach line is simply looping through a list of elements called "reminders", not it's child nodes.
Take a look at this xpath tutorial for more information:
http://www.w3schools.com/xpath/xpath_intro.asp
If you want to use linq with xml (I find it the best way) then you will want to use the System.Xml.Linq namespace. The classes in that namespace are all prefixed with just X not Xml. The functionality in this namespace is newer, better and much easier to manipulate with Linq.
var xml = XDocument.Load("0.xml");
var alarm1 = xml.Descendants("reminder")
.Single(r => r.Element("Title") == "Alarm1");
This code will give you a variable, alarm1 that is the reminder that has a title node of "Alarm1."
From that point its not clear to me exactly what you want to modify. If you just want to change the title then ...
alarm1.Element("Title").Value = "MODIFIED";
xml.Save("0.xml");
XDocument doc = XDocument.Load("0.xml");
IEnumerable<XElement> rech =
from el in doc.Root.Elements("reminder")
where (string)el.Element("Title") == "Alarm1"
select el;
if (rech.Count() != 0)
{
foreach (XElement el in rech)
{
el.Element("Title").SetValue("NEW TITLE");
}
}
doc.Save("0.xml");
XDocument xDoc = XDocument.Load(.....);
xDoc.Descendants("Title").First().Value = "New Value";
xDoc.Save(...)
XmlDocument xml = new XmlDocument();
xml.Load(...);
var newTitle = "MODIFIED";
var title_node = xml.GetElementsByTagName("Title");
if(!string.IsNullOrEmpty(newTitle) && title_node.Count > 0)
{
title_node[0].InnerText = newTitle;
}

Categories