使用 C# LINQ to XML 解析来自国家气象服务 SOAP 服务的 XML

发布于 2024-07-13 16:59:14 字数 5758 浏览 7 评论 0原文

我是一名初级 C# 程序员,正在尝试开发一个库,该库允许我封装解析从 NWS 返回的 XML 并返回表示数据的集合的讨厌细节。

我的 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&amp;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 中的最大和最小临时值放入单独的字符串集合中,同时使用 LINQ 忽略“名称”元素。

编辑: 这是我用来从 Web Reference 获取 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);

I'm a junior C# programmer that's trying to develop a library that will allow me to encapsulate the nasty details of parsing the XML returned from the NWS, and returning a collection representing the data.

My SOAP request would return an XML document in this form:

<?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>

I'm trying to put the maximum and minimum temps that are inside this XML in separate collections of strings while ignoring the "name" elements using LINQ.

Edit:
This is the code I use to get the XML from the Web Reference:

    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);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

巨坚强 2024-07-20 16:59:15

这应该能够为您获得最高温度,您只需更改其中过滤器即可获得最低温度

 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;

希望这会有所帮助。

注意:我对 C# 中的 Linq to Xml 有点生疏,所以它可能不是最优雅的解决方案。

This should be able to get the maximum temperatures for you, you would just have to change the where filter to get the minimums

 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;

Hope this help.

Note: I'm a bit rusty with my Linq to Xml in C# so it may not be the most elegant solution.

じее 2024-07-20 16:59:15

您可能需要解析使用 xpath 返回的 xml 以提取所需的数据。 这里有一个简短的示例

或者,您可以创建一个镜像 xml 结构的类结构,并使用 XmlSerializer 将 xml 反序列化为对象,但在本例中,这可能会带来更多麻烦。

You'll probably need to parse the xml you get back with xpath to pull out the data you want. There's a brief example here.

Alternatively you could create a class structure that mirrors the xml structure and use the XmlSerializer to deserialize the xml into objects, but that's probably more trouble than it's worth in this case.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文