Разбор XML из SOAP-службы Национальной службы погоды в C# LINQ to XML
Я младший программист на C#, который пытается разработать библиотеку, которая позволит мне инкапсулировать неприятные детали парсинга XML, возвращенного из NWS, и возврата коллекции, представляющей данные.
Мой запрос SOAP вернул бы XML-документ в этой форме:
<?xml version="1.0" encoding="UTF-8"?>
<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">2009-02-04T20:01:00Z</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="42.23" longitude="-83.27"/>
</location>
<moreWeatherInformation applicable-location="point1">http://forecast.weather.gov/MapClick.php?textField1=42.23&textField2=-83.27</moreWeatherInformation>
<time-layout time-coordinate="local" summarization="none">
<layout-key>k-p24h-n7-1</layout-key>
<start-valid-time>2009-02-04T07:00:00-05:00</start-valid-time>
<end-valid-time>2009-02-04T19:00:00-05:00</end-valid-time>
<start-valid-time>2009-02-05T07:00:00-05:00</start-valid-time>
<end-valid-time>2009-02-05T19:00:00-05:00</end-valid-time>
<start-valid-time>2009-02-06T07:00:00-05:00</start-valid-time>
<end-valid-time>2009-02-06T19:00:00-05:00</end-valid-time>
<start-valid-time>2009-02-07T07:00:00-05:00</start-valid-time>
<end-valid-time>2009-02-07T19:00:00-05:00</end-valid-time>
<start-valid-time>2009-02-08T07:00:00-05:00</start-valid-time>
<end-valid-time>2009-02-08T19:00:00-05:00</end-valid-time>
<start-valid-time>2009-02-09T07:00:00-05:00</start-valid-time>
<end-valid-time>2009-02-09T19:00:00-05:00</end-valid-time>
<start-valid-time>2009-02-10T07:00:00-05:00</start-valid-time>
<end-valid-time>2009-02-10T19:00:00-05:00</end-valid-time>
</time-layout>
<time-layout time-coordinate="local" summarization="none">
<layout-key>k-p24h-n6-2</layout-key>
<start-valid-time>2009-02-04T19:00:00-05:00</start-valid-time>
<end-valid-time>2009-02-05T08:00:00-05:00</end-valid-time>
<start-valid-time>2009-02-05T19:00:00-05:00</start-valid-time>
<end-valid-time>2009-02-06T08:00:00-05:00</end-valid-time>
<start-valid-time>2009-02-06T19:00:00-05:00</start-valid-time>
<end-valid-time>2009-02-07T08:00:00-05:00</end-valid-time>
<start-valid-time>2009-02-07T19:00:00-05:00</start-valid-time>
<end-valid-time>2009-02-08T08:00:00-05:00</end-valid-time>
<start-valid-time>2009-02-08T19:00:00-05:00</start-valid-time>
<end-valid-time>2009-02-09T08:00:00-05:00</end-valid-time>
<start-valid-time>2009-02-09T19:00:00-05:00</start-valid-time>
<end-valid-time>2009-02-10T08:00:00-05:00</end-valid-time>
</time-layout>
<parameters applicable-location="point1">
<temperature type="maximum" units="Fahrenheit" time-layout="k-p24h-n7-1">
<name>Daily Maximum Temperature</name>
<value>15</value>
<value>19</value>
<value>33</value>
<value>46</value>
<value>41</value>
<value>43</value>
<value>44</value>
</temperature>
<temperature type="minimum" units="Fahrenheit" time-layout="k-p24h-n6-2">
<name>Daily Minimum Temperature</name>
<value>-2</value>
<value>16</value>
<value>29</value>
<value>32</value>
<value>27</value>
<value>32</value>
</temperature>
</parameters>
</data>
</dwml>
Я пытаюсь поместить максимальные и минимальные температуры, которые находятся внутри этого XML, в отдельные коллекции строк, игнорируя элементы "name" с помощью LINQ.
Редактировать: это код, который я использую, чтобы получить XML из веб-ссылки:
WeatherNWS.ndfdXML client = new TestNWS.WeatherNWS.ndfdXML();
string XMLZip = client.LatLonListZipCode("48180");
XElement myElement = XElement.Parse(XMLZip);
string[] myString = myElement.Value.Split(',');
decimal lat = Convert.ToDecimal(myString[0]);
decimal lon = Convert.ToDecimal(myString[1]);
weatherParametersType parameters = new weatherParametersType();
parameters.maxt = true;
parameters.mint = true;
string XML = client.NDFDgen(lat, lon, productType.timeseries, DateTime.Now, DateTime.Now.AddDays(7), parameters);
2 ответа
Это должно быть в состоянии получить максимальные температуры для вас, вам просто нужно изменить фильтр где, чтобы получить минимальные значения
using System.Xml.Linq;
\\...
XDocument xmlDoc = XDocument.Load("YourXml.xml");
var maximums = from tempvalue in xmlDoc.Descendants("temperature").Elements("value")
where tempvalue.Parent.Attribute("type").Value == "maximum"
select (string)tempvalue;
List<string> returnme = maximums.ToList<string>();
return returnme;
Надеюсь, это поможет.
Примечание: я немного заржавел с моим Linq to Xml в C#, поэтому, возможно, это не самое элегантное решение.
Вам, вероятно, потребуется проанализировать xml, который вы вернули, с помощью xpath, чтобы извлечь нужные данные. Вот краткий пример.
В качестве альтернативы вы можете создать структуру класса, которая отражает структуру xml, и использовать XmlSerializer для десериализации xml в объекты, но это, вероятно, больше проблем, чем оно того стоит.