我有以下XML,在预测中有很多" time"节点...超过20,我只留下3作为例子如下。 我能够返回位置数据以及时间属性,但我对降水和云有困难。
<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#comment我的问题(我知道的那个!)是。
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类只包含用于存储数据的getter / setter方法。我的另外两个引用方法是在做同样的事情,但是一个返回一个XmlNodeList而另一个返回一个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 :(得分: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);
}
}
答案 1 :(得分: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();
}
}
}