2015-04-15 5 views
3

Я использую веб-службу погоды в C#. Я передаю ему Lat-Long, и он возвращает прогнозируемый максимум & минимальной температуры в этой области. Ниже код, который я используюИзвлечь данные из XML с помощью XmlDocument

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> 

Я хочу, чтобы извлечь информацию в <time-layout time-coordinate="local" summarization="none"> как start-valid-time, end-valid-time и temperature из <temperature type="maximum" units="Fahrenheit" time-layout="k-p24h-n2-1"> тегов.

Как я могу связаться с этими узлами и перебрать его?

+5

Вы находитесь в правильном направлении ... почему вы ушли? Хотя я бы рекомендовал вместо этого использовать «XDocument». – Jonesopolis

+1

Вы можете перебирать дочерние элементы вашего документа Xml с помощью doc.ChildNodes. Я думаю, вы могли бы использовать запрос LINQ, чтобы получить правильный узел, используя имя. –

+0

@Steven, не могли бы вы запрограммировать код для итерации –

ответ

1

Как указывается в комментариях, с помощью XDocument получит доступ к ряду методов LINQ-to-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 Ahh! Вы правы. Виноват. Я отредактировал свой ответ, чтобы отразить это. Спасибо – LiamK

+0

Нет проблем - но это все равно не сработает. XML, который он хочет получить, фактически встроен в узел CDATA. Он должен быть извлечен, прежде чем его можно будет использовать. –

1

Вам нужно сначала извлечь CDATA, это действительно единственный вызов здесь - тогда вы можете использовать XmlDocument или XDocument или XmlReader. Я бы рекомендовал сделать это таким образом:

и так далее.

Если вы настаиваете на использовании XmlDocument, вы можете использовать тот же метод здесь и просто сделать XmlDocument.LoadFrom(xr.Value), но API XDocument немного более гибкий и будет действовать лучше.

Смежные вопросы