Reputation: 341
I am consuming a weather web service in c#. I am passing it Lat-Long and it returns forecasted maximum & minimum temperature of that area. Following is code that i am using
var response = client.ndfdGen(latlong);
XmlDocument doc = new XmlDocument();
doc.LoadXml(response);
And the following is the response data, that I get i.e. xml response
In this response, there is Latitude and Longitude. I have to extract this.
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:NDFDgenResponse xmlns:ns1="http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl">
<dwmlOut xsi:type="xsd:string"><![CDATA[<?xml version="1.0"?>
<dwml version="1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.nws.noaa.gov/forecasts/xml/DWMLgen/schema/DWML.xsd">
<head>
<product srsName="WGS 1984" concise-name="time-series" operational-mode="official">
<title>NOAA's National Weather Service Forecast Data</title>
<field>meteorological</field>
<category>forecast</category>
<creation-date refresh-frequency="PT1H">2015-04-15T15:13:07Z</creation-date>
</product>
<source>
<more-information>http://www.nws.noaa.gov/forecasts/xml/</more-information>
<production-center>Meteorological Development Laboratory<sub-center>Product Generation Branch</sub-center></production-center>
<disclaimer>http://www.nws.noaa.gov/disclaimer.html</disclaimer>
<credit>http://www.weather.gov/</credit>
<credit-logo>http://www.weather.gov/images/xml_logo.gif</credit-logo>
<feedback>http://www.weather.gov/feedback.php</feedback>
</source>
</head>
<data>
<location>
<location-key>point1</location-key>
<point latitude="39.01" longitude="-77.02"/>
</location>
<moreWeatherInformation applicable-location="point1">http://forecast.weather.gov/MapClick.php?textField1=39.01&textField2=-77.02</moreWeatherInformation>
<time-layout time-coordinate="local" summarization="none">
<layout-key>k-p24h-n2-1</layout-key>
<start-valid-time>2015-04-17T08:00:00-04:00</start-valid-time>
<end-valid-time>2015-04-17T20:00:00-04:00</end-valid-time>
<start-valid-time>2015-04-18T08:00:00-04:00</start-valid-time>
<end-valid-time>2015-04-18T20:00:00-04:00</end-valid-time>
</time-layout>
<parameters applicable-location="point1">
<temperature type="maximum" units="Fahrenheit" time-layout="k-p24h-n2-1">
<name>Daily Maximum Temperature</name>
<value>68</value>
<value>71</value>
</temperature>
</parameters>
</data>
</dwml>]]></dwmlOut>
</ns1:NDFDgenResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
I want to extract information in <time-layout time-coordinate="local" summarization="none">
like start-valid-time
,end-valid-time
and temperature
from <temperature type="maximum" units="Fahrenheit" time-layout="k-p24h-n2-1">
tags.
How can I reach out to these nodes and iterate over it?
Upvotes: 3
Views: 878
Reputation: 815
As suggested in the comments, using XDocument will get you access to a number of LINQ-to-XML methods built for just such a purpose:
// load up the xml into an XDocument
var response = client.ndfdGen(latlong);
var originalDocument = XDocument.Parse(response);
// extract cdata
var cdata = originalDocument.DescendantNodes().OfType<XCData>().First().Value;
var cdataDocument = XDocument.Parse(cdata);
// find the right element via xpath
var myElement = cdataDocument.Root.XPathSelectElement("//dwml/data/location/point");
return myElement.Attribute("latitude").Value;
Note that using the "//" operator in xPath doesn't have great performance. Try nailing down an absolute path once you get the proof of concept working. An explanation of the xPath operations available can be found on MSDN
Upvotes: 1
Reputation: 21641
You're going to have to extract the CDATA first, that's really the only special challenge here - then you can use XmlDocument or XDocument or XmlReader. I'd recommend doing it this way:
var response = client.ndfdGen(latlong);
XDocument xd = null;
using (XmlReader xr = XmlReader.Create(new StringReader(response))) // load the response into an XmlReader
{
xr.ReadToDescendant("dwmlOut"); // go to the dwmlOut node
xr.Read(); // move to the CDATA in that node
xd = XDocument.Parse(xr.Value); // load **that** XML into your XDocument
}
string startTime = xd.Descendants("start-valid-time").First().Value;
and so on.
If you insist on using XmlDocument, you could use the same method here and just do XmlDocument.LoadFrom(xr.Value)
, but the XDocument API is a bit more flexible and will certianly perform better.
Upvotes: 1