提取属性等于特定值的元素的值

时间:2011-10-06 21:35:03

标签: c# xml linq-to-xml

我被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";
}

我似乎尝试过尝试选择元素,属性和后代的所有组合“,但我不知所措。

5 个答案:

答案 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
    }
}