2017-08-19 4 views
0

私は以下のXMLを持っています。予測の下には多くの「時間」ノードがあります... 20歳を超えると、 私はLocationのデータとTimeの属性を返すことができましたが、私は降水量や雲に苦しんでいます。XMLをさまざまなレベルで解析する

<weatherdata> 
    <location> 
     <name>Tokyo</name> 
     <country>JP</country> 
    </location> 
    <forecast> 
     <time from="2017-08-19T12:00:00" to="2017-08-19T15:00:00"> 
      <precipitation unit="3h" value="0.1925" type="rain"/> 
      <clouds value="overcast clouds" all="88" unit="%"/> 
     </time> 
     <time from="2017-08-19T15:00:00" to="2017-08-19T18:00:00"> 
     <precipitation unit="3h" value="0.085000000000001" type="rain"/> 
     <clouds value="overcast clouds" all="92" unit="%"/> 
     </time> 
     <time from="2017-08-19T18:00:00" to="2017-08-19T21:00:00"> 
     <precipitation unit="3h" value="0.7125" type="rain"/> 
     <clouds value="overcast clouds" all="88" unit="%"/> 
     </time> 
    </forecast> 
</weatherdata> 

私の問題(私が知っているもの)は、以下のコードでC#commentwhereとしてマークされています。

using (respStream = resp.GetResponseStream()) 
{ 
    location = new WeatherData.Location.LocationData(); 

    XmlDocument xml = Utility.retrieveXMLDocFromResponse(respStream, "/weatherdata"); 
    location.country = xml.GetElementsByTagName("country")[0].InnerText; 
    location.name = xml.GetElementsByTagName("name")[0].InnerText; 

    forecastList = new List<WeatherData.Forecast.Time>();      
    XmlNodeList xnlNodes = xml.DocumentElement.SelectNodes("/weatherdata/forecast"); 
    foreach (XmlNode xndNode in xnlNodes) 
    { 
     WeatherData.Forecast.Time time = new WeatherData.Forecast.Time(); 
     time.from = xndNode["time"].GetAttribute("from"); 
     time.to = xndNode["time"].GetAttribute("to");     

     // Here I am able to get data for clouds and preciptation, but the loop goes through all the 20 nodes. I just want to return the "preciptation" and "clouds" of the relevant "time" node. 
     XmlNodeList xnlTNodes = xml.DocumentElement.SelectNodes("/weatherdata/forecast/time"); 
     foreach (XmlNode xmlTimeNode in xnlTNodes) 
     { 
      time.clouds = xmlTimeNode["clouds"].GetAttribute("value"); 
      time.precipitation = xmlTimeNode["precipitation"].GetAttribute("type"); 
     } 
     forecastList.Add(time); 
    } 
} 

WeatherDataクラスには、単にデータを格納するゲッター/セッターメソッドが含まれています。私の他の2つの参照メソッドは同じことを以下で行いますが、XmlNodeListともう1つはXMLドキュメントを返します。私は今のクラスへの参照を作成しないだけよう
彼らは静的です:

public static XmlNodeList retrieveXMLResponse(Stream stream, String baseNode) 
{ 
    StreamReader reader = null; 
    XmlElement xelRoot = null; 
    XmlNodeList xnlNodes = null; 

    try 
    { 
     reader = new StreamReader(stream, Encoding.UTF8); 
     string responseString = reader.ReadToEnd(); 
     XmlDocument xmlDoc = new XmlDocument(); 
     xmlDoc.LoadXml(responseString); 

     xelRoot = xmlDoc.DocumentElement; 
     xnlNodes = xelRoot.SelectNodes(baseNode); 
    } 
    finally 
    { 
     reader.Close(); 
    } 

    return xnlNodes; 
} 

public static XmlDocument retrieveXMLDocFromResponse(Stream stream, String baseNode) 
{ 
    StreamReader reader = null; 
    XmlDocument xmlDoc = null; 

    try 
    { 
     reader = new StreamReader(stream, Encoding.UTF8); 
     string responseString = reader.ReadToEnd(); 
     xmlDoc = new XmlDocument(); 
     xmlDoc.LoadXml(responseString); 
    } 
    finally 
    { 
     reader.Close(); 
    } 

    return xmlDoc; 
} 
+0

あなたのコードで何が動作しませんか?すべての時間ノードを選択し、その時間ノードにアクセスすることは大丈夫です。他に何をしたいですか?単に10行目の予測ノードを選択しないでください。 –

答えて

0

を私のコメントで提案されているように、単に代わりにノード時間をかけて反復、forecastノードを選択しないでください。

using (respStream = resp.GetResponseStream()) 
{ 
    location = new WeatherData.Location.LocationData(); 

    XmlDocument xml = Utility.retrieveXMLDocFromResponse(respStream, "/weatherdata"); 
    location.country = xml.GetElementsByTagName("country")[0].InnerText; 
    location.name = xml.GetElementsByTagName("name")[0].InnerText; 

    forecastList = new List<WeatherData.Forecast.Time>();      
    XmlNodeList xnlTNodes = xml.DocumentElement.SelectNodes("/weatherdata/forecast/time"); 
    foreach (XmlNode xmlTimeNode in xnlTNodes) 
    { 

     WeatherData.Forecast.Time time = new WeatherData.Forecast.Time(); 
     time.from = xmlTimeNode .GetAttribute("from"); 
     time.to = xmlTimeNode .GetAttribute("to");       
     time.clouds = xmlTimeNode["clouds"].GetAttribute("value"); 
     time.precipitation = xmlTimeNode["precipitation"].GetAttribute("type"); 
     forecastList.Add(time); 
    } 

} 
+0

こんにちは@Thomas、はい、あなたはxmlTimeNode.GetAttributeを使用することができないことを除いて、十分に簡単に聞こえる、それはオプションではありません。代わりに、xmlTimeNode ["time"] GetAttribute( "from")を使用すると、 "オブジェクト参照がインスタンスオブジェクトに設定されていません" ... – Dragonfly

+0

@Dragonfly: 'XmlNode'の代わりに' XmlElement'を使うことができます。 "xmlTimeNode.Attributes [" from "]。Value'を使用してください。私はどこからGetAttribute()メソッドを持っているのかわかりません。 IMHOはMicrosoftのライブラリの一部ではありません。 –

0

私は、XML LINQを使って好き:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Xml; 
using System.Xml.Linq; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     const string FILENAME = @"c:\temp\test.xml"; 
     static void Main(string[] args) 
     { 
      XDocument doc = XDocument.Load(FILENAME); 

      var weather = doc.Elements("weatherdata").Select(x => new { 
       name = (string)x.Descendants("name").FirstOrDefault(), 
       country = (string)x.Descendants("country").FirstOrDefault(), 
       forecasts = x.Descendants("time").Select(y => new { 
        from = (DateTime)y.Attribute("from"), 
        to = (DateTime)y.Attribute("to"), 
        precipitation = y.Descendants("precipitation").Select(z => new { 
         unit = (string)z.Attribute("unit"), 
         value = (float)z.Attribute("value"), 
         type = (string)z.Attribute("type") 
        }).FirstOrDefault(), 
        clouds = y.Descendants("clouds").Select(z => new { 
         value = (string)z.Attribute("value"), 
         all = (int)z.Attribute("all"), 
         unit = (string)z.Attribute("unit") 
        }).FirstOrDefault() 
       }).ToList() 
      }).FirstOrDefault(); 
     } 
    } 
} 
+2

OPが自分のコードの100%を排除する答えを求めているのかどうかは分かりません。彼は代わりにJQueryを試すこともできます。 –

関連する問題