2015-04-15 153 views
3

我正在使用c#中的天氣Web服務。我將它傳遞給Lat-Long,並返回該區域最低溫度的預測最大值&。下面是我使用使用XmlDocument從XML中提取數據

var response = client.ndfdGen(latlong); 
XmlDocument doc = new XmlDocument(); 
doc.LoadXml(response); 

代碼和以下是響應數據,我得到即xml response 在此迴應,有緯度和經度。 我必須提取這個

<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&amp;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> 

我想從<temperature type="maximum" units="Fahrenheit" time-layout="k-p24h-n2-1">標籤<time-layout time-coordinate="local" summarization="none">提取信息,如start-valid-timeend-valid-timetemperature

如何聯繫到這些節點並對其進行迭代?

+5

你在正確的方向......你爲什麼退出?儘管我建議使用'XDocument'來代替。 – Jonesopolis

+1

您可以使用doc.ChildNodes遍歷Xml文檔的子節點。我想你可以使用LINQ查詢通過使用名稱來獲取正確的節點。 –

+0

@Steven,你可以請代碼來迭代 –

回答

1

正如意見建議,使用的XDocument將讓你獲得了一些只是這樣一個目的內置LINQ到XML的方法:

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

注意使用「//」運營商xPath沒有很好的性能。一旦你獲得了概念證明的工作,試着找出絕對路徑。有關xPath操作的解釋可參見MSDN

+0

這不起作用 - XML位於CDATA段中,並且XDocument.Load()需要一個文件名。你想XDocument.Parse() –

+0

@DanField啊!你是對的。我的錯。我編輯了我的答案以反映這一點。謝謝 – LiamK

+0

沒問題 - 但這仍然行不通。他想要訪問的XML實際上嵌入在CDATA節點中。它必須在使用之前提取。 –

1

您將不得不首先提取CDATA,這實際上是唯一的特殊挑戰 - 那麼您可以使用XmlDocument或XDocument或XmlReader。我推薦這樣做:

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; 

等等。

如果你堅持使用XmlDocument,你可以在這裏使用相同的方法,只是做XmlDocument.LoadFrom(xr.Value),但XDocument API更靈活一些,並且會更好地執行。