我被XDocument再次难倒了。当class属性值为“high”(和“low”)时,我试图提取温度元素的值(本例中为12)
我的XML的一个子集:
<forecastGroup>
<forecast>
<temperatures>
<textSummary>Low plus 2. High 12.</textSummary>
<temperature unitType="metric" units="C" class="high">12</temperature>
<temperature unitType="metric" units="C" class="low">2</temperature>
</temperatures>
</forecast>
...etc.
<forecast>
<temperature unitType="metric" units="C" class="high">15</temperature>
<temperature unitType="metric" units="C" class="low">3</temperature>
</forecast>
<forecastGroup>
到目前为止代码:
XDocument loaded = XDocument.Parse(strInputXML);
foreach (var forecast in loaded.Descendants("forecastGroup").Elements("forecast"))
{
//existing code doing stuff here using the XDocument loaded
High = "this is where I'm lost";
}
我似乎尝试过尝试选择元素,属性和后代的所有组合“,但我不知所措。
答案 0 :(得分:2)
您只需在Linq to XML查询中添加Where()
过滤器:
XDocument loaded = XDocument.Parse(strInputXML);
var matchingForecasts = loaded.Descendants("temperature")
.Where(x => (string)x.Attribute("class") == "high");
foreach (var forecast in matchingForecasts)
{
//do something
string temperature = forecast.Value;
}
或者,您可以查看class
循环中的每个foreach
属性值,这更接近您原来的方法:
foreach (var forecast in loaded.Descendants("temperature"))
{
//existing code doing stuff here using the XDocument loaded
if (forecast.Attribute("class").Value == "high")
{
//do something
string temperature = forecast.Value;
}
}
答案 1 :(得分:1)
loaded.Descendants("temperature")
.Where(d => d.Attribute("class").Value.Equals("high")).First().Value
答案 2 :(得分:1)
要提取循环中的高位,可以使用
行var high = (int)forecast.Element("temperatures")
.Elements("temperature")
.Where(temp => temp.Attribute("class").Value == "high")
.First();
当然,您可以使用Linq-to-XML将整个XML树简单地投影到适当的对象图中,而无需在循环中明确地将其分开,但您应该能够朝着这个方向前进。它可能最终看起来像
var forecasts = from forecast in loaded.Descendants("forecast")
let temps = forecast.Element("temperatures")
let high = temps.Elements("temperature").Where(t => t.Attribute("class").Value == "high").First()
let low = temps.Elements("temperature").Where(t => t.Attribute("class").Value == "low").First()
select new
{
Temperatures = new
{
Summary = temps.Element("textSummary").Value,
High = new
{
UnitType = high.Attribute("unitType").Value,
Units = high.Attribute("units").Value,
Value = (int)high
},
Low = new
{
UnitType = low.Attribute("unitType").Value,
Units = low.Attribute("units").Value,
Value = (int)low
},
}
};
答案 3 :(得分:1)
示例XML文件无效,因为它未正确关闭。
<forecastGroup>
<forecast>
<temperatures>
<textSummary>Low plus 2. High 12.</textSummary>
<temperature unitType="metric" units="C" class="high">12</temperature>
<temperature unitType="metric" units="C" class="low">2</temperature>
</temperatures>
</forecast>
...etc.
<forecast>
<temperature unitType="metric" units="C" class="high">15</temperature>
<temperature unitType="metric" units="C" class="low">3</temperature>
</forecast>
<forecastGroup> // <= this needs to be </forecastGroup>
答案 4 :(得分:0)
您可以尝试使用XPath:
using System.Xml.XPath;
...
string xpathExpression = "forecastGroup/forecast//temperature[@class='high']";
foreach (XElement el in loaded.XPathSelectElements(xpathExpression))
{
int highTemperature = Int32.Parse(el.Value);
}
搜索表达式可能更短("//temperature[@class='high']"
),但更详细地了解值的位置。
如果要使用“高”或“低”类属性值过滤温度,可以使用此xpath表达式:
"forecastGroup/forecast//temperature[@class='high' or @class='low']"
如果您想根据@class属性决定做什么,可以使用以下代码:
string xpathExpression = "forecastGroup/forecast//temperature[@class='high' or @class='low']";
foreach (XElement el in loaded.XPathSelectElements(xpathExpression))
{
int temperature = Int32.Parse(el.Value);
if (el.Attribute("class").Value == "low")
{
// do sth with low value
}
else
{
// do sth with high value
}
}