提取属性等于特定值的元素的值
本文关键字:元素 于特定 属性 提取 | 更新日期: 2023-09-27 18:10:42
我又一次被XDocument难住了。我试图提取温度元素(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";
}
我似乎已经尝试了尝试选择"元素,属性和后代"的每一个组合,但我在一个损失。
您可以在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;
}
或者,您可以查看foreach
循环中的每个class
属性值,这更接近您的原始方法:
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;
}
}
要在循环中提取高点,可以使用
行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
},
}
};
loaded.Descendants("temperature")
.Where(d => d.Attribute("class").Value.Equals("high")).First().Value
示例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>
您可以尝试这样使用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']"
),但更详细地说明值的位置会更有效。
如果想用'high'或'low'类属性值过滤温度,可以使用以下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
}
}